authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-15 13:49:39-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-16 19:37:00-04:00
loge311cd562b47529bdcd2423658915539ddb6bc36
tree5b3d735831183076d83a405042eabebaf8c9c91e
parent59b3dc8907f76b93caa689732e878a5bfa2f65c2

don't automatically take pointer when passing by non-copying value

this commit does not have all tests passing

11 files changed, 249 insertions(+), 272 deletions(-)

src/ir.cpp+34-23
......@@ -10463,13 +10463,6 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ
1046310463 zig_unreachable();
1046410464}
1046510465
10466static IrInstruction *ir_implicit_byval_const_ref_cast(IrAnalyze *ira, IrInstruction *inst) {
10467 if (type_is_copyable(ira->codegen, inst->value.type))
10468 return inst;
10469 TypeTableEntry *const_ref_type = get_pointer_to_type(ira->codegen, inst->value.type, true);
10470 return ir_implicit_cast(ira, inst, const_ref_type);
10471}
10472
1047310466static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {
1047410467 TypeTableEntry *type_entry = ptr->value.type;
1047510468 if (type_is_invalid(type_entry)) {
......@@ -12283,7 +12276,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
1228312276 IrInstruction *casted_arg;
1228412277 if (is_var_args) {
1228512278 arg_part_of_generic_id = true;
12286 casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);
12279 casted_arg = arg;
1228712280 } else {
1228812281 if (param_decl_node->data.param_decl.var_token == nullptr) {
1228912282 AstNode *param_type_node = param_decl_node->data.param_decl.type;
......@@ -12296,7 +12289,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
1229612289 return false;
1229712290 } else {
1229812291 arg_part_of_generic_id = true;
12299 casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);
12292 casted_arg = arg;
1230012293 }
1230112294 }
1230212295
......@@ -12515,9 +12508,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1251512508
1251612509 size_t next_proto_i = 0;
1251712510 if (first_arg_ptr) {
12518 IrInstruction *first_arg;
1251912511 assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);
12520 if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
12512
12513 bool first_arg_known_bare = false;
12514 if (fn_type_id->next_param_index >= 1) {
12515 TypeTableEntry *param_type = fn_type_id->param_info[next_proto_i].type;
12516 if (type_is_invalid(param_type))
12517 return ira->codegen->builtin_types.entry_invalid;
12518 first_arg_known_bare = param_type->id != TypeTableEntryIdPointer;
12519 }
12520
12521 IrInstruction *first_arg;
12522 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
1252112523 first_arg = first_arg_ptr;
1252212524 } else {
1252312525 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
......@@ -12667,9 +12669,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1266712669 size_t next_proto_i = 0;
1266812670
1266912671 if (first_arg_ptr) {
12670 IrInstruction *first_arg;
1267112672 assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);
12672 if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
12673
12674 bool first_arg_known_bare = false;
12675 if (fn_type_id->next_param_index >= 1) {
12676 TypeTableEntry *param_type = fn_type_id->param_info[next_proto_i].type;
12677 if (type_is_invalid(param_type))
12678 return ira->codegen->builtin_types.entry_invalid;
12679 first_arg_known_bare = param_type->id != TypeTableEntryIdPointer;
12680 }
12681
12682 IrInstruction *first_arg;
12683 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
1267312684 first_arg = first_arg_ptr;
1267412685 } else {
1267512686 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
......@@ -12802,10 +12813,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1280212813 return ira->codegen->builtin_types.entry_invalid;
1280312814 }
1280412815 if (inst_fn_type_id.async_allocator_type == nullptr) {
12805 IrInstruction *casted_inst = ir_implicit_byval_const_ref_cast(ira, uncasted_async_allocator_inst);
12806 if (type_is_invalid(casted_inst->value.type))
12807 return ira->codegen->builtin_types.entry_invalid;
12808 inst_fn_type_id.async_allocator_type = casted_inst->value.type;
12816 inst_fn_type_id.async_allocator_type = uncasted_async_allocator_inst->value.type;
1280912817 }
1281012818 async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type);
1281112819 if (type_is_invalid(async_allocator_inst->value.type))
......@@ -12866,9 +12874,16 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1286612874 IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count);
1286712875 size_t next_arg_index = 0;
1286812876 if (first_arg_ptr) {
12869 IrInstruction *first_arg;
1287012877 assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);
12871 if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
12878
12879 TypeTableEntry *param_type = fn_type_id->param_info[next_arg_index].type;
12880 if (type_is_invalid(param_type))
12881 return ira->codegen->builtin_types.entry_invalid;
12882
12883 IrInstruction *first_arg;
12884 if (param_type->id == TypeTableEntryIdPointer &&
12885 handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type))
12886 {
1287212887 first_arg = first_arg_ptr;
1287312888 } else {
1287412889 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
......@@ -12876,10 +12891,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1287612891 return ira->codegen->builtin_types.entry_invalid;
1287712892 }
1287812893
12879 TypeTableEntry *param_type = fn_type_id->param_info[next_arg_index].type;
12880 if (type_is_invalid(param_type))
12881 return ira->codegen->builtin_types.entry_invalid;
12882
1288312894 IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type);
1288412895 if (type_is_invalid(casted_arg->value.type))
1288512896 return ira->codegen->builtin_types.entry_invalid;
std/array_list.zig+13-13
......@@ -29,36 +29,36 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
2929 };
3030 }
3131
32 pub fn deinit(self: *const Self) void {
32 pub fn deinit(self: Self) void {
3333 self.allocator.free(self.items);
3434 }
3535
36 pub fn toSlice(self: *const Self) []align(A) T {
36 pub fn toSlice(self: Self) []align(A) T {
3737 return self.items[0..self.len];
3838 }
3939
40 pub fn toSliceConst(self: *const Self) []align(A) const T {
40 pub fn toSliceConst(self: Self) []align(A) const T {
4141 return self.items[0..self.len];
4242 }
4343
44 pub fn at(self: *const Self, n: usize) T {
44 pub fn at(self: Self, n: usize) T {
4545 return self.toSliceConst()[n];
4646 }
4747
4848 /// Sets the value at index `i`, or returns `error.OutOfBounds` if
4949 /// the index is not in range.
50 pub fn setOrError(self: *const Self, i: usize, item: *const T) !void {
50 pub fn setOrError(self: Self, i: usize, item: T) !void {
5151 if (i >= self.len) return error.OutOfBounds;
52 self.items[i] = item.*;
52 self.items[i] = item;
5353 }
5454
5555 /// Sets the value at index `i`, asserting that the value is in range.
56 pub fn set(self: *const Self, i: usize, item: *const T) void {
56 pub fn set(self: *Self, i: usize, item: T) void {
5757 assert(i < self.len);
58 self.items[i] = item.*;
58 self.items[i] = item;
5959 }
6060
61 pub fn count(self: *const Self) usize {
61 pub fn count(self: Self) usize {
6262 return self.len;
6363 }
6464
......@@ -81,12 +81,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
8181 return result;
8282 }
8383
84 pub fn insert(self: *Self, n: usize, item: *const T) !void {
84 pub fn insert(self: *Self, n: usize, item: T) !void {
8585 try self.ensureCapacity(self.len + 1);
8686 self.len += 1;
8787
8888 mem.copy(T, self.items[n + 1 .. self.len], self.items[n .. self.len - 1]);
89 self.items[n] = item.*;
89 self.items[n] = item;
9090 }
9191
9292 pub fn insertSlice(self: *Self, n: usize, items: []align(A) const T) !void {
......@@ -97,9 +97,9 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
9797 mem.copy(T, self.items[n .. n + items.len], items);
9898 }
9999
100 pub fn append(self: *Self, item: *const T) !void {
100 pub fn append(self: *Self, item: T) !void {
101101 const new_item_ptr = try self.addOne();
102 new_item_ptr.* = item.*;
102 new_item_ptr.* = item;
103103 }
104104
105105 pub fn appendSlice(self: *Self, items: []align(A) const T) !void {
std/build.zig+1-1
......@@ -234,7 +234,7 @@ pub const Builder = struct {
234234 defer wanted_steps.deinit();
235235
236236 if (step_names.len == 0) {
237 try wanted_steps.append(&self.default_step);
237 try wanted_steps.append(self.default_step);
238238 } else {
239239 for (step_names) |step_name| {
240240 const s = try self.getTopLevelStepByName(step_name);
std/fmt/index.zig+6-2
......@@ -162,8 +162,6 @@ pub fn formatType(
162162 },
163163 builtin.TypeInfo.Pointer.Size.Many => {
164164 if (ptr_info.child == u8) {
165 //This is a bit of a hack, but it made more sense to
166 // do this check here than have formatText do it
167165 if (fmt[0] == 's') {
168166 const len = std.cstr.len(value);
169167 return formatText(value[0..len], fmt, context, Errors, output);
......@@ -176,6 +174,12 @@ pub fn formatType(
176174 return output(context, casted_value);
177175 },
178176 },
177 builtin.TypeId.Array => |info| {
178 if (info.child == u8) {
179 return formatText(value, fmt, context, Errors, output);
180 }
181 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(&value));
182 },
179183 else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"),
180184 }
181185}
std/json.zig+1-1
......@@ -1326,7 +1326,7 @@ pub const Parser = struct {
13261326 },
13271327 // Array Parent -> [ ..., <array>, value ]
13281328 Value.Array => |*array| {
1329 try array.append(value);
1329 try array.append(value.*);
13301330 p.state = State.ArrayValue;
13311331 },
13321332 else => {
std/math/big/int.zig+144-202
......@@ -18,39 +18,6 @@ comptime {
1818 debug.assert(Limb.is_signed == false);
1919}
2020
21const wrapped_buffer_size = 512;
22
23// Converts primitive integer values onto a stack-based big integer, or passes through existing
24// Int types with no modifications. This can fail at runtime if using a very large dynamic
25// integer but it is very unlikely and is considered a user error.
26fn wrapInt(allocator: *Allocator, bn: var) *const Int {
27 const T = @typeOf(bn);
28 switch (@typeInfo(T)) {
29 TypeId.Pointer => |info| {
30 if (info.child == Int) {
31 return bn;
32 } else {
33 @compileError("cannot set Int using type " ++ @typeName(T));
34 }
35 },
36 else => {
37 var s = allocator.create(Int) catch unreachable;
38 s.* = Int{
39 .allocator = allocator,
40 .positive = false,
41 .limbs = block: {
42 var limbs = allocator.alloc(Limb, Int.default_capacity) catch unreachable;
43 limbs[0] = 0;
44 break :block limbs;
45 },
46 .len = 1,
47 };
48 s.set(bn) catch unreachable;
49 return s;
50 },
51 }
52}
53
5421pub const Int = struct {
5522 allocator: *Allocator,
5623 positive: bool,
......@@ -93,11 +60,11 @@ pub const Int = struct {
9360 self.limbs = try self.allocator.realloc(Limb, self.limbs, capacity);
9461 }
9562
96 pub fn deinit(self: *const Int) void {
63 pub fn deinit(self: Int) void {
9764 self.allocator.free(self.limbs);
9865 }
9966
100 pub fn clone(other: *const Int) !Int {
67 pub fn clone(other: Int) !Int {
10168 return Int{
10269 .allocator = other.allocator,
10370 .positive = other.positive,
......@@ -110,8 +77,8 @@ pub const Int = struct {
11077 };
11178 }
11279
113 pub fn copy(self: *Int, other: *const Int) !void {
114 if (self == other) {
80 pub fn copy(self: *Int, other: Int) !void {
81 if (self == &other) {
11582 return;
11683 }
11784
......@@ -125,7 +92,7 @@ pub const Int = struct {
12592 mem.swap(Int, self, other);
12693 }
12794
128 pub fn dump(self: *const Int) void {
95 pub fn dump(self: Int) void {
12996 for (self.limbs) |limb| {
13097 debug.warn("{x} ", limb);
13198 }
......@@ -140,20 +107,20 @@ pub const Int = struct {
140107 r.positive = true;
141108 }
142109
143 pub fn isOdd(r: *const Int) bool {
110 pub fn isOdd(r: Int) bool {
144111 return r.limbs[0] & 1 != 0;
145112 }
146113
147 pub fn isEven(r: *const Int) bool {
114 pub fn isEven(r: Int) bool {
148115 return !r.isOdd();
149116 }
150117
151 fn bitcount(self: *const Int) usize {
118 fn bitcount(self: Int) usize {
152119 const u_bit_count = (self.len - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len - 1]));
153120 return usize(!self.positive) + u_bit_count;
154121 }
155122
156 pub fn sizeInBase(self: *const Int, base: usize) usize {
123 pub fn sizeInBase(self: Int, base: usize) usize {
157124 return (self.bitcount() / math.log2(base)) + 1;
158125 }
159126
......@@ -219,7 +186,7 @@ pub const Int = struct {
219186 TargetTooSmall,
220187 };
221188
222 pub fn to(self: *const Int, comptime T: type) ConvertError!T {
189 pub fn to(self: Int, comptime T: type) ConvertError!T {
223190 switch (@typeId(T)) {
224191 TypeId.Int => {
225192 const UT = if (T.is_signed) @IntType(false, T.bit_count - 1) else T;
......@@ -286,16 +253,28 @@ pub const Int = struct {
286253 i += 1;
287254 }
288255
256 // TODO values less than limb size should guarantee non allocating
257 var base_buffer: [512]u8 = undefined;
258 const base_al = &std.heap.FixedBufferAllocator.init(base_buffer[0..]).allocator;
259 const base_ap = try Int.initSet(base_al, base);
260
261 var d_buffer: [512]u8 = undefined;
262 var d_fba = std.heap.FixedBufferAllocator.init(d_buffer[0..]);
263 const d_al = &d_fba.allocator;
264
289265 try self.set(0);
290266 for (value[i..]) |ch| {
291267 const d = try charToDigit(ch, base);
292 try self.mul(self, base);
293 try self.add(self, d);
268 d_fba.end_index = 0;
269 const d_ap = try Int.initSet(d_al, d);
270
271 try self.mul(self.*, base_ap);
272 try self.add(self.*, d_ap);
294273 }
295274 self.positive = positive;
296275 }
297276
298 pub fn toString(self: *const Int, allocator: *Allocator, base: u8) ![]const u8 {
277 pub fn toString(self: Int, allocator: *Allocator, base: u8) ![]const u8 {
299278 if (base < 2 or base > 16) {
300279 return error.InvalidBase;
301280 }
......@@ -345,7 +324,7 @@ pub const Int = struct {
345324 var b = try Int.initSet(allocator, limb_base);
346325
347326 while (q.len >= 2) {
348 try Int.divTrunc(&q, &r, &q, &b);
327 try Int.divTrunc(&q, &r, q, b);
349328
350329 var r_word = r.limbs[0];
351330 var i: usize = 0;
......@@ -378,12 +357,7 @@ pub const Int = struct {
378357 }
379358
380359 // returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively.
381 pub fn cmpAbs(a: *const Int, bv: var) i8 {
382 // TODO: Thread-local buffer.
383 var buffer: [wrapped_buffer_size]u8 = undefined;
384 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
385 var b = wrapInt(&stack.allocator, bv);
386
360 pub fn cmpAbs(a: Int, b: Int) i8 {
387361 if (a.len < b.len) {
388362 return -1;
389363 }
......@@ -408,11 +382,7 @@ pub const Int = struct {
408382 }
409383
410384 // returns -1, 0, 1 if a < b, a == b or a > b respectively.
411 pub fn cmp(a: *const Int, bv: var) i8 {
412 var buffer: [wrapped_buffer_size]u8 = undefined;
413 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
414 var b = wrapInt(&stack.allocator, bv);
415
385 pub fn cmp(a: Int, b: Int) i8 {
416386 if (a.positive != b.positive) {
417387 return if (a.positive) i8(1) else -1;
418388 } else {
......@@ -422,17 +392,17 @@ pub const Int = struct {
422392 }
423393
424394 // if a == 0
425 pub fn eqZero(a: *const Int) bool {
395 pub fn eqZero(a: Int) bool {
426396 return a.len == 1 and a.limbs[0] == 0;
427397 }
428398
429399 // if |a| == |b|
430 pub fn eqAbs(a: *const Int, b: var) bool {
400 pub fn eqAbs(a: Int, b: Int) bool {
431401 return cmpAbs(a, b) == 0;
432402 }
433403
434404 // if a == b
435 pub fn eq(a: *const Int, b: var) bool {
405 pub fn eq(a: Int, b: Int) bool {
436406 return cmp(a, b) == 0;
437407 }
438408
......@@ -473,12 +443,7 @@ pub const Int = struct {
473443 }
474444
475445 // r = a + b
476 pub fn add(r: *Int, av: var, bv: var) Allocator.Error!void {
477 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
478 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
479 var a = wrapInt(&stack.allocator, av);
480 var b = wrapInt(&stack.allocator, bv);
481
446 pub fn add(r: *Int, a: Int, b: Int) Allocator.Error!void {
482447 if (a.eqZero()) {
483448 try r.copy(b);
484449 return;
......@@ -547,12 +512,7 @@ pub const Int = struct {
547512 }
548513
549514 // r = a - b
550 pub fn sub(r: *Int, av: var, bv: var) !void {
551 var buffer: [wrapped_buffer_size]u8 = undefined;
552 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
553 var a = wrapInt(&stack.allocator, av);
554 var b = wrapInt(&stack.allocator, bv);
555
515 pub fn sub(r: *Int, a: Int, b: Int) !void {
556516 if (a.positive != b.positive) {
557517 if (a.positive) {
558518 // (a) - (-b) => a + b
......@@ -632,14 +592,9 @@ pub const Int = struct {
632592 // rma = a * b
633593 //
634594 // For greatest efficiency, ensure rma does not alias a or b.
635 pub fn mul(rma: *Int, av: var, bv: var) !void {
636 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
637 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
638 var a = wrapInt(&stack.allocator, av);
639 var b = wrapInt(&stack.allocator, bv);
640
595 pub fn mul(rma: *Int, a: Int, b: Int) !void {
641596 var r = rma;
642 var aliased = rma == a or rma == b;
597 var aliased = rma.limbs.ptr == a.limbs.ptr or rma.limbs.ptr == b.limbs.ptr;
643598
644599 var sr: Int = undefined;
645600 if (aliased) {
......@@ -714,29 +669,29 @@ pub const Int = struct {
714669 }
715670 }
716671
717 pub fn divFloor(q: *Int, r: *Int, a: var, b: var) !void {
672 pub fn divFloor(q: *Int, r: *Int, a: Int, b: Int) !void {
718673 try div(q, r, a, b);
719674
720675 // Trunc -> Floor.
721676 if (!q.positive) {
722 try q.sub(q, 1);
723 try r.add(q, 1);
677 // TODO values less than limb size should guarantee non allocating
678 var one_buffer: [512]u8 = undefined;
679 const one_al = &std.heap.FixedBufferAllocator.init(one_buffer[0..]).allocator;
680 const one_ap = try Int.initSet(one_al, 1);
681
682 try q.sub(q.*, one_ap);
683 try r.add(q.*, one_ap);
724684 }
725685 r.positive = b.positive;
726686 }
727687
728 pub fn divTrunc(q: *Int, r: *Int, a: var, b: var) !void {
688 pub fn divTrunc(q: *Int, r: *Int, a: Int, b: Int) !void {
729689 try div(q, r, a, b);
730690 r.positive = a.positive;
731691 }
732692
733693 // Truncates by default.
734 fn div(quo: *Int, rem: *Int, av: var, bv: var) !void {
735 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
736 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
737 var a = wrapInt(&stack.allocator, av);
738 var b = wrapInt(&stack.allocator, bv);
739
694 fn div(quo: *Int, rem: *Int, a: Int, b: Int) !void {
740695 if (b.eqZero()) {
741696 @panic("division by zero");
742697 }
......@@ -821,8 +776,8 @@ pub const Int = struct {
821776
822777 // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set)
823778 const norm_shift = @clz(y.limbs[y.len - 1]);
824 try x.shiftLeft(x, norm_shift);
825 try y.shiftLeft(y, norm_shift);
779 try x.shiftLeft(x.*, norm_shift);
780 try y.shiftLeft(y.*, norm_shift);
826781
827782 const n = x.len - 1;
828783 const t = y.len - 1;
......@@ -832,10 +787,10 @@ pub const Int = struct {
832787 mem.set(Limb, q.limbs[0..q.len], 0);
833788
834789 // 2.
835 try tmp.shiftLeft(y, Limb.bit_count * (n - t));
836 while (x.cmp(&tmp) >= 0) {
790 try tmp.shiftLeft(y.*, Limb.bit_count * (n - t));
791 while (x.cmp(tmp) >= 0) {
837792 q.limbs[n - t] += 1;
838 try x.sub(x, tmp);
793 try x.sub(x.*, tmp);
839794 }
840795
841796 // 3.
......@@ -864,7 +819,7 @@ pub const Int = struct {
864819 r.limbs[2] = carry;
865820 r.normN(3);
866821
867 if (r.cmpAbs(&tmp) <= 0) {
822 if (r.cmpAbs(tmp) <= 0) {
868823 break;
869824 }
870825
......@@ -873,13 +828,13 @@ pub const Int = struct {
873828
874829 // 3.3
875830 try tmp.set(q.limbs[i - t - 1]);
876 try tmp.mul(&tmp, y);
877 try tmp.shiftLeft(&tmp, Limb.bit_count * (i - t - 1));
878 try x.sub(x, &tmp);
831 try tmp.mul(tmp, y.*);
832 try tmp.shiftLeft(tmp, Limb.bit_count * (i - t - 1));
833 try x.sub(x.*, tmp);
879834
880835 if (!x.positive) {
881 try tmp.shiftLeft(y, Limb.bit_count * (i - t - 1));
882 try x.add(x, &tmp);
836 try tmp.shiftLeft(y.*, Limb.bit_count * (i - t - 1));
837 try x.add(x.*, tmp);
883838 q.limbs[i - t - 1] -= 1;
884839 }
885840 }
......@@ -887,16 +842,12 @@ pub const Int = struct {
887842 // Denormalize
888843 q.normN(q.len);
889844
890 try r.shiftRight(x, norm_shift);
845 try r.shiftRight(x.*, norm_shift);
891846 r.normN(r.len);
892847 }
893848
894849 // r = a << shift, in other words, r = a * 2^shift
895 pub fn shiftLeft(r: *Int, av: var, shift: usize) !void {
896 var buffer: [wrapped_buffer_size]u8 = undefined;
897 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
898 var a = wrapInt(&stack.allocator, av);
899
850 pub fn shiftLeft(r: *Int, a: Int, shift: usize) !void {
900851 try r.ensureCapacity(a.len + (shift / Limb.bit_count) + 1);
901852 llshl(r.limbs[0..], a.limbs[0..a.len], shift);
902853 r.norm1(a.len + (shift / Limb.bit_count) + 1);
......@@ -927,11 +878,7 @@ pub const Int = struct {
927878 }
928879
929880 // r = a >> shift
930 pub fn shiftRight(r: *Int, av: var, shift: usize) !void {
931 var buffer: [wrapped_buffer_size]u8 = undefined;
932 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
933 var a = wrapInt(&stack.allocator, av);
934
881 pub fn shiftRight(r: *Int, a: Int, shift: usize) !void {
935882 if (a.len <= shift / Limb.bit_count) {
936883 r.len = 1;
937884 r.limbs[0] = 0;
......@@ -966,12 +913,7 @@ pub const Int = struct {
966913 }
967914
968915 // r = a | b
969 pub fn bitOr(r: *Int, av: var, bv: var) !void {
970 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
971 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
972 var a = wrapInt(&stack.allocator, av);
973 var b = wrapInt(&stack.allocator, bv);
974
916 pub fn bitOr(r: *Int, a: Int, b: Int) !void {
975917 if (a.len > b.len) {
976918 try r.ensureCapacity(a.len);
977919 llor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
......@@ -998,12 +940,7 @@ pub const Int = struct {
998940 }
999941
1000942 // r = a & b
1001 pub fn bitAnd(r: *Int, av: var, bv: var) !void {
1002 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
1003 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
1004 var a = wrapInt(&stack.allocator, av);
1005 var b = wrapInt(&stack.allocator, bv);
1006
943 pub fn bitAnd(r: *Int, a: Int, b: Int) !void {
1007944 if (a.len > b.len) {
1008945 try r.ensureCapacity(b.len);
1009946 lland(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
......@@ -1027,12 +964,7 @@ pub const Int = struct {
1027964 }
1028965
1029966 // r = a ^ b
1030 pub fn bitXor(r: *Int, av: var, bv: var) !void {
1031 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
1032 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
1033 var a = wrapInt(&stack.allocator, av);
1034 var b = wrapInt(&stack.allocator, bv);
1035
967 pub fn bitXor(r: *Int, a: Int, b: Int) !void {
1036968 if (a.len > b.len) {
1037969 try r.ensureCapacity(a.len);
1038970 llxor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
......@@ -1065,7 +997,7 @@ pub const Int = struct {
1065997// may be untested in some cases.
1066998
1067999const u256 = @IntType(false, 256);
1068var al = debug.global_allocator;
1000const al = debug.global_allocator;
10691001
10701002test "big.int comptime_int set" {
10711003 comptime var s = 0xefffffff00000001eeeeeeefaaaaaaab;
......@@ -1198,7 +1130,7 @@ test "big.int bitcount + sizeInBase" {
11981130 debug.assert(a.sizeInBase(2) >= 32);
11991131 debug.assert(a.sizeInBase(10) >= 10);
12001132
1201 try a.shiftLeft(&a, 5000);
1133 try a.shiftLeft(a, 5000);
12021134 debug.assert(a.bitcount() == 5032);
12031135 debug.assert(a.sizeInBase(2) >= 5032);
12041136 a.positive = false;
......@@ -1320,40 +1252,40 @@ test "big.int compare" {
13201252 var a = try Int.initSet(al, -11);
13211253 var b = try Int.initSet(al, 10);
13221254
1323 debug.assert(a.cmpAbs(&b) == 1);
1324 debug.assert(a.cmp(&b) == -1);
1255 debug.assert(a.cmpAbs(b) == 1);
1256 debug.assert(a.cmp(b) == -1);
13251257}
13261258
13271259test "big.int compare similar" {
13281260 var a = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeee);
13291261 var b = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeef);
13301262
1331 debug.assert(a.cmpAbs(&b) == -1);
1332 debug.assert(b.cmpAbs(&a) == 1);
1263 debug.assert(a.cmpAbs(b) == -1);
1264 debug.assert(b.cmpAbs(a) == 1);
13331265}
13341266
13351267test "big.int compare different limb size" {
13361268 var a = try Int.initSet(al, @maxValue(Limb) + 1);
13371269 var b = try Int.initSet(al, 1);
13381270
1339 debug.assert(a.cmpAbs(&b) == 1);
1340 debug.assert(b.cmpAbs(&a) == -1);
1271 debug.assert(a.cmpAbs(b) == 1);
1272 debug.assert(b.cmpAbs(a) == -1);
13411273}
13421274
13431275test "big.int compare multi-limb" {
13441276 var a = try Int.initSet(al, -0x7777777799999999ffffeeeeffffeeeeffffeeeef);
13451277 var b = try Int.initSet(al, 0x7777777799999999ffffeeeeffffeeeeffffeeeee);
13461278
1347 debug.assert(a.cmpAbs(&b) == 1);
1348 debug.assert(a.cmp(&b) == -1);
1279 debug.assert(a.cmpAbs(b) == 1);
1280 debug.assert(a.cmp(b) == -1);
13491281}
13501282
13511283test "big.int equality" {
13521284 var a = try Int.initSet(al, 0xffffffff1);
13531285 var b = try Int.initSet(al, -0xffffffff1);
13541286
1355 debug.assert(a.eqAbs(&b));
1356 debug.assert(!a.eq(&b));
1287 debug.assert(a.eqAbs(b));
1288 debug.assert(!a.eq(b));
13571289}
13581290
13591291test "big.int abs" {
......@@ -1381,7 +1313,7 @@ test "big.int add single-single" {
13811313 var b = try Int.initSet(al, 5);
13821314
13831315 var c = try Int.init(al);
1384 try c.add(&a, &b);
1316 try c.add(a, b);
13851317
13861318 debug.assert((try c.to(u32)) == 55);
13871319}
......@@ -1392,10 +1324,10 @@ test "big.int add multi-single" {
13921324
13931325 var c = try Int.init(al);
13941326
1395 try c.add(&a, &b);
1327 try c.add(a, b);
13961328 debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2);
13971329
1398 try c.add(&b, &a);
1330 try c.add(b, a);
13991331 debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2);
14001332}
14011333
......@@ -1406,7 +1338,7 @@ test "big.int add multi-multi" {
14061338 var b = try Int.initSet(al, op2);
14071339
14081340 var c = try Int.init(al);
1409 try c.add(&a, &b);
1341 try c.add(a, b);
14101342
14111343 debug.assert((try c.to(u128)) == op1 + op2);
14121344}
......@@ -1416,7 +1348,7 @@ test "big.int add zero-zero" {
14161348 var b = try Int.initSet(al, 0);
14171349
14181350 var c = try Int.init(al);
1419 try c.add(&a, &b);
1351 try c.add(a, b);
14201352
14211353 debug.assert((try c.to(u32)) == 0);
14221354}
......@@ -1426,7 +1358,7 @@ test "big.int add alias multi-limb nonzero-zero" {
14261358 var a = try Int.initSet(al, op1);
14271359 var b = try Int.initSet(al, 0);
14281360
1429 try a.add(&a, &b);
1361 try a.add(a, b);
14301362
14311363 debug.assert((try a.to(u128)) == op1);
14321364}
......@@ -1434,16 +1366,21 @@ test "big.int add alias multi-limb nonzero-zero" {
14341366test "big.int add sign" {
14351367 var a = try Int.init(al);
14361368
1437 try a.add(1, 2);
1369 const one = try Int.initSet(al, 1);
1370 const two = try Int.initSet(al, 2);
1371 const neg_one = try Int.initSet(al, -1);
1372 const neg_two = try Int.initSet(al, -2);
1373
1374 try a.add(one, two);
14381375 debug.assert((try a.to(i32)) == 3);
14391376
1440 try a.add(-1, 2);
1377 try a.add(neg_one, two);
14411378 debug.assert((try a.to(i32)) == 1);
14421379
1443 try a.add(1, -2);
1380 try a.add(one, neg_two);
14441381 debug.assert((try a.to(i32)) == -1);
14451382
1446 try a.add(-1, -2);
1383 try a.add(neg_one, neg_two);
14471384 debug.assert((try a.to(i32)) == -3);
14481385}
14491386
......@@ -1452,7 +1389,7 @@ test "big.int sub single-single" {
14521389 var b = try Int.initSet(al, 5);
14531390
14541391 var c = try Int.init(al);
1455 try c.sub(&a, &b);
1392 try c.sub(a, b);
14561393
14571394 debug.assert((try c.to(u32)) == 45);
14581395}
......@@ -1462,7 +1399,7 @@ test "big.int sub multi-single" {
14621399 var b = try Int.initSet(al, 1);
14631400
14641401 var c = try Int.init(al);
1465 try c.sub(&a, &b);
1402 try c.sub(a, b);
14661403
14671404 debug.assert((try c.to(Limb)) == @maxValue(Limb));
14681405}
......@@ -1475,7 +1412,7 @@ test "big.int sub multi-multi" {
14751412 var b = try Int.initSet(al, op2);
14761413
14771414 var c = try Int.init(al);
1478 try c.sub(&a, &b);
1415 try c.sub(a, b);
14791416
14801417 debug.assert((try c.to(u128)) == op1 - op2);
14811418}
......@@ -1485,7 +1422,7 @@ test "big.int sub equal" {
14851422 var b = try Int.initSet(al, 0x11efefefefefefefefefefefef);
14861423
14871424 var c = try Int.init(al);
1488 try c.sub(&a, &b);
1425 try c.sub(a, b);
14891426
14901427 debug.assert((try c.to(u32)) == 0);
14911428}
......@@ -1493,19 +1430,24 @@ test "big.int sub equal" {
14931430test "big.int sub sign" {
14941431 var a = try Int.init(al);
14951432
1496 try a.sub(1, 2);
1433 const one = try Int.initSet(al, 1);
1434 const two = try Int.initSet(al, 2);
1435 const neg_one = try Int.initSet(al, -1);
1436 const neg_two = try Int.initSet(al, -2);
1437
1438 try a.sub(one, two);
14971439 debug.assert((try a.to(i32)) == -1);
14981440
1499 try a.sub(-1, 2);
1441 try a.sub(neg_one, two);
15001442 debug.assert((try a.to(i32)) == -3);
15011443
1502 try a.sub(1, -2);
1444 try a.sub(one, neg_two);
15031445 debug.assert((try a.to(i32)) == 3);
15041446
1505 try a.sub(-1, -2);
1447 try a.sub(neg_one, neg_two);
15061448 debug.assert((try a.to(i32)) == 1);
15071449
1508 try a.sub(-2, -1);
1450 try a.sub(neg_two, neg_one);
15091451 debug.assert((try a.to(i32)) == -1);
15101452}
15111453
......@@ -1514,7 +1456,7 @@ test "big.int mul single-single" {
15141456 var b = try Int.initSet(al, 5);
15151457
15161458 var c = try Int.init(al);
1517 try c.mul(&a, &b);
1459 try c.mul(a, b);
15181460
15191461 debug.assert((try c.to(u64)) == 250);
15201462}
......@@ -1524,7 +1466,7 @@ test "big.int mul multi-single" {
15241466 var b = try Int.initSet(al, 2);
15251467
15261468 var c = try Int.init(al);
1527 try c.mul(&a, &b);
1469 try c.mul(a, b);
15281470
15291471 debug.assert((try c.to(DoubleLimb)) == 2 * @maxValue(Limb));
15301472}
......@@ -1536,7 +1478,7 @@ test "big.int mul multi-multi" {
15361478 var b = try Int.initSet(al, op2);
15371479
15381480 var c = try Int.init(al);
1539 try c.mul(&a, &b);
1481 try c.mul(a, b);
15401482
15411483 debug.assert((try c.to(u256)) == op1 * op2);
15421484}
......@@ -1545,7 +1487,7 @@ test "big.int mul alias r with a" {
15451487 var a = try Int.initSet(al, @maxValue(Limb));
15461488 var b = try Int.initSet(al, 2);
15471489
1548 try a.mul(&a, &b);
1490 try a.mul(a, b);
15491491
15501492 debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb));
15511493}
......@@ -1554,7 +1496,7 @@ test "big.int mul alias r with b" {
15541496 var a = try Int.initSet(al, @maxValue(Limb));
15551497 var b = try Int.initSet(al, 2);
15561498
1557 try a.mul(&b, &a);
1499 try a.mul(b, a);
15581500
15591501 debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb));
15601502}
......@@ -1562,7 +1504,7 @@ test "big.int mul alias r with b" {
15621504test "big.int mul alias r with a and b" {
15631505 var a = try Int.initSet(al, @maxValue(Limb));
15641506
1565 try a.mul(&a, &a);
1507 try a.mul(a, a);
15661508
15671509 debug.assert((try a.to(DoubleLimb)) == @maxValue(Limb) * @maxValue(Limb));
15681510}
......@@ -1572,7 +1514,7 @@ test "big.int mul a*0" {
15721514 var b = try Int.initSet(al, 0);
15731515
15741516 var c = try Int.init(al);
1575 try c.mul(&a, &b);
1517 try c.mul(a, b);
15761518
15771519 debug.assert((try c.to(u32)) == 0);
15781520}
......@@ -1582,7 +1524,7 @@ test "big.int mul 0*0" {
15821524 var b = try Int.initSet(al, 0);
15831525
15841526 var c = try Int.init(al);
1585 try c.mul(&a, &b);
1527 try c.mul(a, b);
15861528
15871529 debug.assert((try c.to(u32)) == 0);
15881530}
......@@ -1593,7 +1535,7 @@ test "big.int div single-single no rem" {
15931535
15941536 var q = try Int.init(al);
15951537 var r = try Int.init(al);
1596 try Int.divTrunc(&q, &r, &a, &b);
1538 try Int.divTrunc(&q, &r, a, b);
15971539
15981540 debug.assert((try q.to(u32)) == 10);
15991541 debug.assert((try r.to(u32)) == 0);
......@@ -1605,7 +1547,7 @@ test "big.int div single-single with rem" {
16051547
16061548 var q = try Int.init(al);
16071549 var r = try Int.init(al);
1608 try Int.divTrunc(&q, &r, &a, &b);
1550 try Int.divTrunc(&q, &r, a, b);
16091551
16101552 debug.assert((try q.to(u32)) == 9);
16111553 debug.assert((try r.to(u32)) == 4);
......@@ -1620,7 +1562,7 @@ test "big.int div multi-single no rem" {
16201562
16211563 var q = try Int.init(al);
16221564 var r = try Int.init(al);
1623 try Int.divTrunc(&q, &r, &a, &b);
1565 try Int.divTrunc(&q, &r, a, b);
16241566
16251567 debug.assert((try q.to(u64)) == op1 / op2);
16261568 debug.assert((try r.to(u64)) == 0);
......@@ -1635,7 +1577,7 @@ test "big.int div multi-single with rem" {
16351577
16361578 var q = try Int.init(al);
16371579 var r = try Int.init(al);
1638 try Int.divTrunc(&q, &r, &a, &b);
1580 try Int.divTrunc(&q, &r, a, b);
16391581
16401582 debug.assert((try q.to(u64)) == op1 / op2);
16411583 debug.assert((try r.to(u64)) == 3);
......@@ -1650,7 +1592,7 @@ test "big.int div multi>2-single" {
16501592
16511593 var q = try Int.init(al);
16521594 var r = try Int.init(al);
1653 try Int.divTrunc(&q, &r, &a, &b);
1595 try Int.divTrunc(&q, &r, a, b);
16541596
16551597 debug.assert((try q.to(u128)) == op1 / op2);
16561598 debug.assert((try r.to(u32)) == 0x3e4e);
......@@ -1662,7 +1604,7 @@ test "big.int div single-single q < r" {
16621604
16631605 var q = try Int.init(al);
16641606 var r = try Int.init(al);
1665 try Int.divTrunc(&q, &r, &a, &b);
1607 try Int.divTrunc(&q, &r, a, b);
16661608
16671609 debug.assert((try q.to(u64)) == 0);
16681610 debug.assert((try r.to(u64)) == 0x0078f432);
......@@ -1674,7 +1616,7 @@ test "big.int div single-single q == r" {
16741616
16751617 var q = try Int.init(al);
16761618 var r = try Int.init(al);
1677 try Int.divTrunc(&q, &r, &a, &b);
1619 try Int.divTrunc(&q, &r, a, b);
16781620
16791621 debug.assert((try q.to(u64)) == 1);
16801622 debug.assert((try r.to(u64)) == 0);
......@@ -1684,7 +1626,7 @@ test "big.int div q=0 alias" {
16841626 var a = try Int.initSet(al, 3);
16851627 var b = try Int.initSet(al, 10);
16861628
1687 try Int.divTrunc(&a, &b, &a, &b);
1629 try Int.divTrunc(&a, &b, a, b);
16881630
16891631 debug.assert((try a.to(u64)) == 0);
16901632 debug.assert((try b.to(u64)) == 3);
......@@ -1698,7 +1640,7 @@ test "big.int div multi-multi q < r" {
16981640
16991641 var q = try Int.init(al);
17001642 var r = try Int.init(al);
1701 try Int.divTrunc(&q, &r, &a, &b);
1643 try Int.divTrunc(&q, &r, a, b);
17021644
17031645 debug.assert((try q.to(u128)) == 0);
17041646 debug.assert((try r.to(u128)) == op1);
......@@ -1713,7 +1655,7 @@ test "big.int div trunc single-single +/+" {
17131655
17141656 var q = try Int.init(al);
17151657 var r = try Int.init(al);
1716 try Int.divTrunc(&q, &r, &a, &b);
1658 try Int.divTrunc(&q, &r, a, b);
17171659
17181660 // n = q * d + r
17191661 // 5 = 1 * 3 + 2
......@@ -1733,7 +1675,7 @@ test "big.int div trunc single-single -/+" {
17331675
17341676 var q = try Int.init(al);
17351677 var r = try Int.init(al);
1736 try Int.divTrunc(&q, &r, &a, &b);
1678 try Int.divTrunc(&q, &r, a, b);
17371679
17381680 // n = q * d + r
17391681 // -5 = 1 * -3 - 2
......@@ -1753,7 +1695,7 @@ test "big.int div trunc single-single +/-" {
17531695
17541696 var q = try Int.init(al);
17551697 var r = try Int.init(al);
1756 try Int.divTrunc(&q, &r, &a, &b);
1698 try Int.divTrunc(&q, &r, a, b);
17571699
17581700 // n = q * d + r
17591701 // 5 = -1 * -3 + 2
......@@ -1773,7 +1715,7 @@ test "big.int div trunc single-single -/-" {
17731715
17741716 var q = try Int.init(al);
17751717 var r = try Int.init(al);
1776 try Int.divTrunc(&q, &r, &a, &b);
1718 try Int.divTrunc(&q, &r, a, b);
17771719
17781720 // n = q * d + r
17791721 // -5 = 1 * -3 - 2
......@@ -1793,7 +1735,7 @@ test "big.int div floor single-single +/+" {
17931735
17941736 var q = try Int.init(al);
17951737 var r = try Int.init(al);
1796 try Int.divFloor(&q, &r, &a, &b);
1738 try Int.divFloor(&q, &r, a, b);
17971739
17981740 // n = q * d + r
17991741 // 5 = 1 * 3 + 2
......@@ -1813,7 +1755,7 @@ test "big.int div floor single-single -/+" {
18131755
18141756 var q = try Int.init(al);
18151757 var r = try Int.init(al);
1816 try Int.divFloor(&q, &r, &a, &b);
1758 try Int.divFloor(&q, &r, a, b);
18171759
18181760 // n = q * d + r
18191761 // -5 = -2 * 3 + 1
......@@ -1833,7 +1775,7 @@ test "big.int div floor single-single +/-" {
18331775
18341776 var q = try Int.init(al);
18351777 var r = try Int.init(al);
1836 try Int.divFloor(&q, &r, &a, &b);
1778 try Int.divFloor(&q, &r, a, b);
18371779
18381780 // n = q * d + r
18391781 // 5 = -2 * -3 - 1
......@@ -1853,7 +1795,7 @@ test "big.int div floor single-single -/-" {
18531795
18541796 var q = try Int.init(al);
18551797 var r = try Int.init(al);
1856 try Int.divFloor(&q, &r, &a, &b);
1798 try Int.divFloor(&q, &r, a, b);
18571799
18581800 // n = q * d + r
18591801 // -5 = 2 * -3 + 1
......@@ -1870,7 +1812,7 @@ test "big.int div multi-multi with rem" {
18701812
18711813 var q = try Int.init(al);
18721814 var r = try Int.init(al);
1873 try Int.divTrunc(&q, &r, &a, &b);
1815 try Int.divTrunc(&q, &r, a, b);
18741816
18751817 debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
18761818 debug.assert((try r.to(u128)) == 0x28de0acacd806823638);
......@@ -1882,7 +1824,7 @@ test "big.int div multi-multi no rem" {
18821824
18831825 var q = try Int.init(al);
18841826 var r = try Int.init(al);
1885 try Int.divTrunc(&q, &r, &a, &b);
1827 try Int.divTrunc(&q, &r, a, b);
18861828
18871829 debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
18881830 debug.assert((try r.to(u128)) == 0);
......@@ -1894,7 +1836,7 @@ test "big.int div multi-multi (2 branch)" {
18941836
18951837 var q = try Int.init(al);
18961838 var r = try Int.init(al);
1897 try Int.divTrunc(&q, &r, &a, &b);
1839 try Int.divTrunc(&q, &r, a, b);
18981840
18991841 debug.assert((try q.to(u128)) == 0x10000000000000000);
19001842 debug.assert((try r.to(u128)) == 0x44444443444444431111111111111111);
......@@ -1906,7 +1848,7 @@ test "big.int div multi-multi (3.1/3.3 branch)" {
19061848
19071849 var q = try Int.init(al);
19081850 var r = try Int.init(al);
1909 try Int.divTrunc(&q, &r, &a, &b);
1851 try Int.divTrunc(&q, &r, a, b);
19101852
19111853 debug.assert((try q.to(u128)) == 0xfffffffffffffffffff);
19121854 debug.assert((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282);
......@@ -1943,17 +1885,17 @@ test "big.int shift-left multi" {
19431885test "big.int shift-right negative" {
19441886 var a = try Int.init(al);
19451887
1946 try a.shiftRight(-20, 2);
1888 try a.shiftRight(try Int.initSet(al, -20), 2);
19471889 debug.assert((try a.to(i32)) == -20 >> 2);
19481890
1949 try a.shiftRight(-5, 10);
1891 try a.shiftRight(try Int.initSet(al, -5), 10);
19501892 debug.assert((try a.to(i32)) == -5 >> 10);
19511893}
19521894
19531895test "big.int shift-left negative" {
19541896 var a = try Int.init(al);
19551897
1956 try a.shiftRight(-10, 1232);
1898 try a.shiftRight(try Int.initSet(al, -10), 1232);
19571899 debug.assert((try a.to(i32)) == -10 >> 1232);
19581900}
19591901
......@@ -1961,7 +1903,7 @@ test "big.int bitwise and simple" {
19611903 var a = try Int.initSet(al, 0xffffffff11111111);
19621904 var b = try Int.initSet(al, 0xeeeeeeee22222222);
19631905
1964 try a.bitAnd(&a, &b);
1906 try a.bitAnd(a, b);
19651907
19661908 debug.assert((try a.to(u64)) == 0xeeeeeeee00000000);
19671909}
......@@ -1970,7 +1912,7 @@ test "big.int bitwise and multi-limb" {
19701912 var a = try Int.initSet(al, @maxValue(Limb) + 1);
19711913 var b = try Int.initSet(al, @maxValue(Limb));
19721914
1973 try a.bitAnd(&a, &b);
1915 try a.bitAnd(a, b);
19741916
19751917 debug.assert((try a.to(u128)) == 0);
19761918}
......@@ -1979,7 +1921,7 @@ test "big.int bitwise xor simple" {
19791921 var a = try Int.initSet(al, 0xffffffff11111111);
19801922 var b = try Int.initSet(al, 0xeeeeeeee22222222);
19811923
1982 try a.bitXor(&a, &b);
1924 try a.bitXor(a, b);
19831925
19841926 debug.assert((try a.to(u64)) == 0x1111111133333333);
19851927}
......@@ -1988,7 +1930,7 @@ test "big.int bitwise xor multi-limb" {
19881930 var a = try Int.initSet(al, @maxValue(Limb) + 1);
19891931 var b = try Int.initSet(al, @maxValue(Limb));
19901932
1991 try a.bitXor(&a, &b);
1933 try a.bitXor(a, b);
19921934
19931935 debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) ^ @maxValue(Limb));
19941936}
......@@ -1997,7 +1939,7 @@ test "big.int bitwise or simple" {
19971939 var a = try Int.initSet(al, 0xffffffff11111111);
19981940 var b = try Int.initSet(al, 0xeeeeeeee22222222);
19991941
2000 try a.bitOr(&a, &b);
1942 try a.bitOr(a, b);
20011943
20021944 debug.assert((try a.to(u64)) == 0xffffffff33333333);
20031945}
......@@ -2006,7 +1948,7 @@ test "big.int bitwise or multi-limb" {
20061948 var a = try Int.initSet(al, @maxValue(Limb) + 1);
20071949 var b = try Int.initSet(al, @maxValue(Limb));
20081950
2009 try a.bitOr(&a, &b);
1951 try a.bitOr(a, b);
20101952
20111953 // TODO: big.int.cpp or is wrong on multi-limb.
20121954 debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) + @maxValue(Limb));
......@@ -2015,9 +1957,9 @@ test "big.int bitwise or multi-limb" {
20151957test "big.int var args" {
20161958 var a = try Int.initSet(al, 5);
20171959
2018 try a.add(&a, 6);
1960 try a.add(a, try Int.initSet(al, 6));
20191961 debug.assert((try a.to(u64)) == 11);
20201962
2021 debug.assert(a.cmp(11) == 0);
2022 debug.assert(a.cmp(14) <= 0);
1963 debug.assert(a.cmp(try Int.initSet(al, 11)) == 0);
1964 debug.assert(a.cmp(try Int.initSet(al, 14)) <= 0);
20231965}
std/mem.zig+3-7
......@@ -40,16 +40,12 @@ pub const Allocator = struct {
4040
4141 /// Call destroy with the result
4242 /// TODO once #733 is solved, this will replace create
43 pub fn construct(self: *Allocator, init: var) t: {
44 // TODO this is a workaround for type getting parsed as Error!&const T
45 const T = @typeOf(init).Child;
46 break :t Error!*T;
47 } {
48 const T = @typeOf(init).Child;
43 pub fn construct(self: *Allocator, init: var) Error!*@typeOf(init) {
44 const T = @typeOf(init);
4945 if (@sizeOf(T) == 0) return &{};
5046 const slice = try self.alloc(T, 1);
5147 const ptr = &slice[0];
52 ptr.* = init.*;
48 ptr.* = init;
5349 return ptr;
5450 }
5551
test/cases/cast.zig-8
......@@ -318,14 +318,6 @@ fn testCastConstArrayRefToConstSlice() void {
318318 assert(mem.eql(u8, slice, "aoeu"));
319319}
320320
321test "var args implicitly casts by value arg to const ref" {
322 foo("hello");
323}
324
325fn foo(args: ...) void {
326 assert(@typeOf(args[0]) == *const [5]u8);
327}
328
329321test "peer type resolution: error and [N]T" {
330322 // TODO: implicit error!T to error!U where T can implicitly cast to U
331323 //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
test/cases/fn.zig+46-2
......@@ -121,7 +121,7 @@ test "assign inline fn to const variable" {
121121inline fn inlineFn() void {}
122122
123123test "pass by non-copying value" {
124 assert(bar(Point{ .x = 1, .y = 2 }) == 3);
124 assert(addPointCoords(Point{ .x = 1, .y = 2 }) == 3);
125125}
126126
127127const Point = struct {
......@@ -129,6 +129,50 @@ const Point = struct {
129129 y: i32,
130130};
131131
132fn bar(pt: Point) i32 {
132fn addPointCoords(pt: Point) i32 {
133133 return pt.x + pt.y;
134134}
135
136test "pass by non-copying value through var arg" {
137 assert(addPointCoordsVar(Point{ .x = 1, .y = 2 }) == 3);
138}
139
140fn addPointCoordsVar(pt: var) i32 {
141 comptime assert(@typeOf(pt) == Point);
142 return pt.x + pt.y;
143}
144
145test "pass by non-copying value as method" {
146 var pt = Point2{ .x = 1, .y = 2 };
147 assert(pt.addPointCoords() == 3);
148}
149
150const Point2 = struct {
151 x: i32,
152 y: i32,
153
154 fn addPointCoords(self: Point2) i32 {
155 return self.x + self.y;
156 }
157};
158
159test "pass by non-copying value as method, which is generic" {
160 var pt = Point3{ .x = 1, .y = 2 };
161 assert(pt.addPointCoords(i32) == 3);
162}
163
164const Point3 = struct {
165 x: i32,
166 y: i32,
167
168 fn addPointCoords(self: Point3, comptime T: type) i32 {
169 return self.x + self.y;
170 }
171};
172
173test "pass by non-copying value as method, at comptime" {
174 comptime {
175 var pt = Point2{ .x = 1, .y = 2 };
176 assert(pt.addPointCoords() == 3);
177 }
178}
test/cases/var_args.zig-12
......@@ -75,18 +75,6 @@ test "array of var args functions" {
7575 assert(!foos[1]());
7676}
7777
78test "pass array and slice of same array to var args should have same pointers" {
79 const array = "hi";
80 const slice: []const u8 = array;
81 return assertSlicePtrsEql(array, slice);
82}
83
84fn assertSlicePtrsEql(args: ...) void {
85 const s1 = ([]const u8)(args[0]);
86 const s2 = args[1];
87 assert(s1.ptr == s2.ptr);
88}
89
9078test "pass zero length array to var args param" {
9179 doNothingWithFirstArg("");
9280}
test/compile_errors.zig+1-1
......@@ -2215,7 +2215,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
22152215 \\ derp.init();
22162216 \\}
22172217 ,
2218 ".tmp_source.zig:14:5: error: expected type 'i32', found '*const Foo'",
2218 ".tmp_source.zig:14:5: error: expected type 'i32', found 'Foo'",
22192219 );
22202220
22212221 cases.add(