Commit 7611ed3484
src/ir.cpp
@@ -5751,6 +5751,10 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
return false;
}
+static bool is_slice(TypeTableEntry *type) {
+ return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice;
+}
+
enum ImplicitCastMatchResult {
ImplicitCastMatchResultNo,
ImplicitCastMatchResultYes,
@@ -5837,6 +5841,22 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
}
}
+ // implicit [N]T to &const []const N
+ if (expected_type->id == TypeTableEntryIdPointer &&
+ expected_type->data.pointer.is_const &&
+ is_slice(expected_type->data.pointer.child_type) &&
+ actual_type->id == TypeTableEntryIdArray)
+ {
+ TypeTableEntry *ptr_type =
+ expected_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
+ assert(ptr_type->id == TypeTableEntryIdPointer);
+ if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
+ types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
+ {
+ return ImplicitCastMatchResultYes;
+ }
+ }
+
// implicit number literal to typed number
// implicit number literal to &const integer
if (actual_type->id == TypeTableEntryIdNumLitFloat ||
@@ -5883,10 +5903,6 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
return ImplicitCastMatchResultNo;
}
-static bool is_slice(TypeTableEntry *type) {
- return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice;
-}
-
static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, IrInstruction **instructions, size_t instruction_count) {
assert(instruction_count >= 1);
IrInstruction *prev_inst = instructions[0];
@@ -6860,6 +6876,30 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
}
}
+ // explicit cast from [N]T to &const []const N
+ if (wanted_type->id == TypeTableEntryIdPointer &&
+ wanted_type->data.pointer.is_const &&
+ is_slice(wanted_type->data.pointer.child_type) &&
+ actual_type->id == TypeTableEntryIdArray)
+ {
+ TypeTableEntry *ptr_type =
+ wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
+ assert(ptr_type->id == TypeTableEntryIdPointer);
+ if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
+ types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
+ {
+ IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value);
+ if (type_is_invalid(cast1->value.type))
+ return ira->codegen->invalid_instruction;
+
+ IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
+ if (type_is_invalid(cast2->value.type))
+ return ira->codegen->invalid_instruction;
+
+ return cast2;
+ }
+ }
+
// explicit cast from []T to []u8 or []u8 to []T
if (is_slice(wanted_type) && is_slice(actual_type) &&
(is_u8(wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type) ||
std/build.zig
@@ -119,30 +119,30 @@ pub const Builder = struct {
var zig_args = List([]const u8).init(self.allocator);
defer zig_args.deinit();
- %return zig_args.append("build_exe"[0...]); // TODO issue #296
+ %return zig_args.append("build_exe");
%return zig_args.append(exe.root_src);
if (exe.verbose) {
- %return zig_args.append("--verbose"[0...]); // TODO issue #296
+ %return zig_args.append("--verbose");
}
if (exe.release) {
- %return zig_args.append("--release"[0...]); // TODO issue #296
+ %return zig_args.append("--release");
}
- %return zig_args.append("--name"[0...]); // TODO issue #296
+ %return zig_args.append("--name");
%return zig_args.append(exe.name);
switch (exe.target) {
Target.Native => {},
Target.Cross => |cross_target| {
- %return zig_args.append("--target-arch"[0...]); // TODO issue #296
+ %return zig_args.append("--target-arch");
%return zig_args.append(targetArchName(cross_target.arch));
- %return zig_args.append("--target-os"[0...]); // TODO issue #296
+ %return zig_args.append("--target-os");
%return zig_args.append(targetOsName(cross_target.os));
- %return zig_args.append("--target-environ"[0...]); // TODO issue #296
+ %return zig_args.append("--target-environ");
%return zig_args.append(targetEnvironName(cross_target.environ));
},
}
@@ -153,11 +153,11 @@ pub const Builder = struct {
const tmp_file_name = "linker.ld.tmp"; // TODO issue #298
io.writeFile(tmp_file_name, script, self.allocator)
%% |err| debug.panic("unable to write linker script: {}\n", @errorName(err));
- %return zig_args.append("--linker-script"[0...]); // TODO issue #296
- %return zig_args.append(tmp_file_name[0...]); // TODO issue #296
+ %return zig_args.append("--linker-script");
+ %return zig_args.append(tmp_file_name);
},
LinkerScript.Path => |path| {
- %return zig_args.append("--linker-script"[0...]); // TODO issue #296
+ %return zig_args.append("--linker-script");
%return zig_args.append(path);
},
}
@@ -166,23 +166,23 @@ pub const Builder = struct {
var it = exe.link_libs.iterator();
while (true) {
const entry = it.next() ?? break;
- %return zig_args.append("--library"[0...]); // TODO issue #296
+ %return zig_args.append("--library");
%return zig_args.append(entry.key);
}
}
for (self.include_paths.toSliceConst()) |include_path| {
- %return zig_args.append("-isystem"[0...]); // TODO issue #296
+ %return zig_args.append("-isystem");
%return zig_args.append(include_path);
}
for (self.rpaths.toSliceConst()) |rpath| {
- %return zig_args.append("-rpath"[0...]); // TODO issue #296
+ %return zig_args.append("-rpath");
%return zig_args.append(rpath);
}
for (self.lib_paths.toSliceConst()) |lib_path| {
- %return zig_args.append("--library-path"[0...]); // TODO issue #296
+ %return zig_args.append("--library-path");
%return zig_args.append(lib_path);
}
test/cases/cast.zig
@@ -70,3 +70,8 @@ test "integer literal to &const int" {
const x: &const i32 = 3;
assert(*x == 3);
}
+
+test "string literal to &const []const u8" {
+ const x: &const []const u8 = "hello";
+ assert(mem.eql(u8, *x, "hello"));
+}