allow implicit cast from [N]T to &const []const T

closes #296
This commit is contained in:
Andrew Kelley 2017-04-07 17:56:01 -04:00
parent 5eb78ba177
commit 7611ed3484
3 changed files with 63 additions and 18 deletions

View File

@ -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) ||

View File

@ -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);
}

View File

@ -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"));
}