diff --git a/doc/langref.html.in b/doc/langref.html.in index 3ed8d9d3ae..87d73c987c 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -3052,32 +3052,6 @@ fn createFoo(param: i32) !Foo { The {#syntax#}errdefer{#endsyntax#} statement can optionally capture the error:
{#code|test_errdefer_capture.zig#} - {#header_close#} - {#header_open|Common errdefer Slip-Ups#} -- It should be noted that {#syntax#}errdefer{#endsyntax#} statements only last until the end of the block - they are written in, and therefore are not run if an error is returned outside of that block: -
- {#code|test_errdefer_slip_ups.zig#} - -- To ensure that {#syntax#}deallocateFoo{#endsyntax#} is properly called - when returning an error, you must add an {#syntax#}errdefer{#endsyntax#} outside of the block: -
- {#code|test_errdefer_block.zig#} - -- The fact that errdefers only last for the block they are declared in is - especially important when using loops: -
- {#code|test_errdefer_loop_leak.zig#} - -- Special care must be taken with code that allocates in a loop - to make sure that no memory is leaked when returning an error: -
- {#code|test_errdefer_loop.zig#} - {#header_close#}A couple of other tidbits about error handling: diff --git a/doc/langref/test_errdefer_block.zig b/doc/langref/test_errdefer_block.zig deleted file mode 100644 index 6afef099a6..0000000000 --- a/doc/langref/test_errdefer_block.zig +++ /dev/null @@ -1,42 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; - -const Foo = struct { - data: u32, -}; - -fn tryToAllocateFoo(allocator: Allocator) !*Foo { - return allocator.create(Foo); -} - -fn deallocateFoo(allocator: Allocator, foo: *Foo) void { - allocator.destroy(foo); -} - -fn getFooData() !u32 { - return 666; -} - -fn createFoo(allocator: Allocator, param: i32) !*Foo { - const foo = getFoo: { - var foo = try tryToAllocateFoo(allocator); - errdefer deallocateFoo(allocator, foo); - - foo.data = try getFooData(); - - break :getFoo foo; - }; - // This lasts for the rest of the function - errdefer deallocateFoo(allocator, foo); - - // Error is now properly handled by errdefer - if (param > 1337) return error.InvalidParam; - - return foo; -} - -test "createFoo" { - try std.testing.expectError(error.InvalidParam, createFoo(std.testing.allocator, 2468)); -} - -// test diff --git a/doc/langref/test_errdefer_loop.zig b/doc/langref/test_errdefer_loop.zig deleted file mode 100644 index 23de5eaa7a..0000000000 --- a/doc/langref/test_errdefer_loop.zig +++ /dev/null @@ -1,36 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; - -const Foo = struct { data: *u32 }; - -fn getData() !u32 { - return 666; -} - -fn genFoos(allocator: Allocator, num: usize) ![]Foo { - const foos = try allocator.alloc(Foo, num); - errdefer allocator.free(foos); - - // Used to track how many foos have been initialized - // (including their data being allocated) - var num_allocated: usize = 0; - errdefer for (foos[0..num_allocated]) |foo| { - allocator.destroy(foo.data); - }; - for (foos, 0..) |*foo, i| { - foo.data = try allocator.create(u32); - num_allocated += 1; - - if (i >= 3) return error.TooManyFoos; - - foo.data.* = try getData(); - } - - return foos; -} - -test "genFoos" { - try std.testing.expectError(error.TooManyFoos, genFoos(std.testing.allocator, 5)); -} - -// test diff --git a/doc/langref/test_errdefer_loop_leak.zig b/doc/langref/test_errdefer_loop_leak.zig deleted file mode 100644 index 8aa2327ef5..0000000000 --- a/doc/langref/test_errdefer_loop_leak.zig +++ /dev/null @@ -1,32 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; - -const Foo = struct { data: *u32 }; - -fn getData() !u32 { - return 666; -} - -fn genFoos(allocator: Allocator, num: usize) ![]Foo { - const foos = try allocator.alloc(Foo, num); - errdefer allocator.free(foos); - - for (foos, 0..) |*foo, i| { - foo.data = try allocator.create(u32); - // This errdefer does not last between iterations - errdefer allocator.destroy(foo.data); - - // The data for the first 3 foos will be leaked - if (i >= 3) return error.TooManyFoos; - - foo.data.* = try getData(); - } - - return foos; -} - -test "genFoos" { - try std.testing.expectError(error.TooManyFoos, genFoos(std.testing.allocator, 5)); -} - -// test_error=3 errors were logged diff --git a/doc/langref/test_errdefer_slip_ups.zig b/doc/langref/test_errdefer_slip_ups.zig deleted file mode 100644 index ca4b658f89..0000000000 --- a/doc/langref/test_errdefer_slip_ups.zig +++ /dev/null @@ -1,42 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; - -const Foo = struct { - data: u32, -}; - -fn tryToAllocateFoo(allocator: Allocator) !*Foo { - return allocator.create(Foo); -} - -fn deallocateFoo(allocator: Allocator, foo: *Foo) void { - allocator.destroy(foo); -} - -fn getFooData() !u32 { - return 666; -} - -fn createFoo(allocator: Allocator, param: i32) !*Foo { - const foo = getFoo: { - var foo = try tryToAllocateFoo(allocator); - errdefer deallocateFoo(allocator, foo); // Only lasts until the end of getFoo - - // Calls deallocateFoo on error - foo.data = try getFooData(); - - break :getFoo foo; - }; - - // Outside of the scope of the errdefer, so - // deallocateFoo will not be called here - if (param > 1337) return error.InvalidParam; - - return foo; -} - -test "createFoo" { - try std.testing.expectError(error.InvalidParam, createFoo(std.testing.allocator, 2468)); -} - -// test_error=1 tests leaked memory