Skip to content

Commit

Permalink
Merge branch 'master' into add-linker-version-arg
Browse files Browse the repository at this point in the history
  • Loading branch information
matteo-briani authored Jun 23, 2023
2 parents a2e928c + 64faaa7 commit b084f76
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 333 deletions.
2 changes: 1 addition & 1 deletion doc/docgen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1305,7 +1305,7 @@ fn genHtml(
defer root_node.end();

var env_map = try process.getEnvMap(allocator);
try env_map.put("ZIG_DEBUG_COLOR", "1");
try env_map.put("YES_COLOR", "1");

const host = try std.zig.system.NativeTargetInfo.detect(.{});
const builtin_code = try getBuiltinCode(allocator, &env_map, zig_exe, opt_zig_lib_dir);
Expand Down
18 changes: 17 additions & 1 deletion doc/langref.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -5584,7 +5584,7 @@ fn doAThing(str: []u8) !void {
appropriately.
</p>
<p>
Finally, you may want to take a different action for every situation. For that, we combine
You may want to take a different action for every situation. For that, we combine
the {#link|if#} and {#link|switch#} expression:
</p>
{#syntax_block|zig|handle_all_error_scenarios.zig#}
Expand All @@ -5598,6 +5598,22 @@ fn doAThing(str: []u8) void {
// we promise that InvalidChar won't happen (or crash in debug mode if it does)
error.InvalidChar => unreachable,
}
}
{#end_syntax_block#}
<p>
Finally, you may want to handle only some errors. For that, you can capture the unhandled
errors in the {#syntax#}else{#endsyntax#} case, which now contains a narrower error set:
</p>
{#syntax_block|zig|handle_some_error_scenarios.zig#}
fn doAnotherThing(str: []u8) error{InvaidChar}!void {
if (parseU64(str, 10)) |number| {
doSomethingWithNumber(number);
} else |err| switch (err) {
error.Overflow => {
// handle overflow...
},
else => |leftover_err| return leftover_err,
}
}
{#end_syntax_block#}
<p>
Expand Down
2 changes: 1 addition & 1 deletion lib/build_runner.zig
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ pub fn main() !void {
const ttyconf = get_tty_conf(color, stderr);
switch (ttyconf) {
.no_color => try builder.env_map.put("NO_COLOR", "1"),
.escape_codes => try builder.env_map.put("ZIG_DEBUG_COLOR", "1"),
.escape_codes => try builder.env_map.put("YES_COLOR", "1"),
.windows_api => {},
}

Expand Down
33 changes: 19 additions & 14 deletions lib/std/io/tty.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,34 @@ const native_os = builtin.os.tag;

/// Detect suitable TTY configuration options for the given file (commonly stdout/stderr).
/// This includes feature checks for ANSI escape codes and the Windows console API, as well as
/// respecting the `NO_COLOR` environment variable.
/// respecting the `NO_COLOR` and `YES_COLOR` environment variables to override the default.
pub fn detectConfig(file: File) Config {
if (builtin.os.tag == .wasi) {
// Per https://github.com/WebAssembly/WASI/issues/162 ANSI codes
// aren't currently supported.
return .no_color;
} else if (process.hasEnvVarConstant("ZIG_DEBUG_COLOR")) {
return .escape_codes;
} else if (process.hasEnvVarConstant("NO_COLOR")) {
return .no_color;
} else if (file.supportsAnsiEscapeCodes()) {
return .escape_codes;
} else if (native_os == .windows and file.isTty()) {
const force_color: ?bool = if (builtin.os.tag == .wasi)
null // wasi does not support environment variables
else if (process.hasEnvVarConstant("NO_COLOR"))
false
else if (process.hasEnvVarConstant("YES_COLOR"))
true
else
null;

if (force_color == false) return .no_color;

if (native_os == .windows and file.isTty()) {
var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) {
// TODO: Should this return an error instead?
return .no_color;
return if (force_color == true) .escape_codes else .no_color;
}
return .{ .windows_api = .{
.handle = file.handle,
.reset_attributes = info.wAttributes,
} };
}

if (force_color == true or file.supportsAnsiEscapeCodes()) {
return .escape_codes;
}

return .no_color;
}

Expand Down
36 changes: 25 additions & 11 deletions lib/std/sort.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ pub fn insertion(
/// O(1) memory (no allocator required).
/// Sorts in ascending order with respect to the given `lessThan` function.
pub fn insertionContext(a: usize, b: usize, context: anytype) void {
assert(a <= b);

var i = a + 1;
while (i < b) : (i += 1) {
var j = i;
Expand Down Expand Up @@ -73,6 +75,7 @@ pub fn heap(
/// O(1) memory (no allocator required).
/// Sorts in ascending order with respect to the given `lessThan` function.
pub fn heapContext(a: usize, b: usize, context: anytype) void {
assert(a <= b);
// build the heap in linear time.
var i = a + (b - a) / 2;
while (i > a) {
Expand All @@ -89,22 +92,33 @@ pub fn heapContext(a: usize, b: usize, context: anytype) void {
}
}

fn siftDown(a: usize, root: usize, n: usize, context: anytype) void {
var node = root;
fn siftDown(a: usize, target: usize, b: usize, context: anytype) void {
var cur = target;
while (true) {
var child = a + 2 * (node - a) + 1;
if (child >= n) break;
// When we don't overflow from the multiply below, the following expression equals (2*cur) - (2*a) + a + 1
// The `+ a + 1` is safe because:
// for `a > 0` then `2a >= a + 1`.
// for `a = 0`, the expression equals `2*cur+1`. `2*cur` is an even number, therefore adding 1 is safe.
var child = (math.mul(usize, cur - a, 2) catch break) + a + 1;

// stop if we overshot the boundary
if (!(child < b)) break;

// choose the greater child.
child += @intFromBool(child + 1 < n and context.lessThan(child, child + 1));
// `next_child` is at most `b`, therefore no overflow is possible
const next_child = child + 1;

// store the greater child in `child`
if (next_child < b and context.lessThan(child, next_child)) {
child = next_child;
}

// stop if the invariant holds at `node`.
if (!context.lessThan(node, child)) break;
// stop if the Heap invariant holds at `cur`.
if (context.lessThan(child, cur)) break;

// swap `node` with the greater child,
// swap `cur` with the greater child,
// move one step down, and continue sifting.
context.swap(node, child);
node = child;
context.swap(child, cur);
cur = child;
}
}

Expand Down
11 changes: 4 additions & 7 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8273,7 +8273,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError

if (try sema.resolveMaybeUndefVal(enum_tag)) |enum_tag_val| {
const val = try enum_tag_val.intFromEnum(enum_tag_ty, mod);
return sema.addConstant(int_tag_ty, try val.copy(sema.arena));
return sema.addConstant(int_tag_ty, val);
}

try sema.requireRuntimeBlock(block, src, operand_src);
Expand Down Expand Up @@ -28723,14 +28723,11 @@ fn beginComptimePtrMutation(
// without making a call to this function.
const arena = sema.arena;

const repeated_val = try val_ptr.castTag(.repeated).?.data.copy(arena);
const repeated_val = try val_ptr.castTag(.repeated).?.data.intern(parent.ty.childType(mod), mod);
const array_len_including_sentinel =
try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod));
const elems = try arena.alloc(Value, array_len_including_sentinel);
if (elems.len > 0) elems[0] = repeated_val;
for (elems[1..]) |*elem| {
elem.* = try repeated_val.copy(arena);
}
@memset(elems, repeated_val.toValue());

val_ptr.* = try Value.Tag.aggregate.create(arena, elems);

Expand Down Expand Up @@ -36421,7 +36418,7 @@ fn valuesEqual(
rhs: Value,
ty: Type,
) CompileError!bool {
return Value.eqlAdvanced(lhs, ty, rhs, ty, sema.mod, sema);
return lhs.eql(rhs, ty, sema.mod);
}

/// Asserts the values are comparable vectors of type `ty`.
Expand Down
8 changes: 0 additions & 8 deletions src/type.zig
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,6 @@ pub const Type = struct {
return a.toIntern() == b.toIntern();
}

pub fn hash(ty: Type, mod: *const Module) u32 {
_ = mod; // TODO: remove this parameter
// The InternPool data structure hashes based on Key to make interned objects
// unique. An Index can be treated simply as u32 value for the
// purpose of Type/Value hashing and equality.
return std.hash.uint32(@intFromEnum(ty.toIntern()));
}

pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
_ = ty;
_ = unused_fmt_string;
Expand Down
Loading

0 comments on commit b084f76

Please sign in to comment.