authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-07 17:56:01-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-07 17:56:01-04:00
log7611ed3484ad810fe10d3c303a04d66bfa0bd6fd
treedc0b432b5abc0b0cb46e917f2fa30ae99e4ba515
parent5eb78ba1772b54af1ecfb1cd28cb0f1c46dab9b3

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

closes #296

3 files changed, 63 insertions(+), 18 deletions(-)

src/ir.cpp+44-4
......@@ -5751,6 +5751,10 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
57515751 return false;
57525752}
57535753
5754static bool is_slice(TypeTableEntry *type) {
5755 return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice;
5756}
5757
57545758enum ImplicitCastMatchResult {
57555759 ImplicitCastMatchResultNo,
57565760 ImplicitCastMatchResultYes,
......@@ -5837,6 +5841,22 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
58375841 }
58385842 }
58395843
5844 // implicit [N]T to &const []const N
5845 if (expected_type->id == TypeTableEntryIdPointer &&
5846 expected_type->data.pointer.is_const &&
5847 is_slice(expected_type->data.pointer.child_type) &&
5848 actual_type->id == TypeTableEntryIdArray)
5849 {
5850 TypeTableEntry *ptr_type =
5851 expected_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
5852 assert(ptr_type->id == TypeTableEntryIdPointer);
5853 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
5854 types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
5855 {
5856 return ImplicitCastMatchResultYes;
5857 }
5858 }
5859
58405860 // implicit number literal to typed number
58415861 // implicit number literal to &const integer
58425862 if (actual_type->id == TypeTableEntryIdNumLitFloat ||
......@@ -5883,10 +5903,6 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
58835903 return ImplicitCastMatchResultNo;
58845904}
58855905
5886static bool is_slice(TypeTableEntry *type) {
5887 return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice;
5888}
5889
58905906static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, IrInstruction **instructions, size_t instruction_count) {
58915907 assert(instruction_count >= 1);
58925908 IrInstruction *prev_inst = instructions[0];
......@@ -6860,6 +6876,30 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
68606876 }
68616877 }
68626878
6879 // explicit cast from [N]T to &const []const N
6880 if (wanted_type->id == TypeTableEntryIdPointer &&
6881 wanted_type->data.pointer.is_const &&
6882 is_slice(wanted_type->data.pointer.child_type) &&
6883 actual_type->id == TypeTableEntryIdArray)
6884 {
6885 TypeTableEntry *ptr_type =
6886 wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
6887 assert(ptr_type->id == TypeTableEntryIdPointer);
6888 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
6889 types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
6890 {
6891 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value);
6892 if (type_is_invalid(cast1->value.type))
6893 return ira->codegen->invalid_instruction;
6894
6895 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
6896 if (type_is_invalid(cast2->value.type))
6897 return ira->codegen->invalid_instruction;
6898
6899 return cast2;
6900 }
6901 }
6902
68636903 // explicit cast from []T to []u8 or []u8 to []T
68646904 if (is_slice(wanted_type) && is_slice(actual_type) &&
68656905 (is_u8(wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type) ||
std/build.zig+14-14
......@@ -119,30 +119,30 @@ pub const Builder = struct {
119119 var zig_args = List([]const u8).init(self.allocator);
120120 defer zig_args.deinit();
121121
122 %return zig_args.append("build_exe"[0...]); // TODO issue #296
122 %return zig_args.append("build_exe");
123123 %return zig_args.append(exe.root_src);
124124
125125 if (exe.verbose) {
126 %return zig_args.append("--verbose"[0...]); // TODO issue #296
126 %return zig_args.append("--verbose");
127127 }
128128
129129 if (exe.release) {
130 %return zig_args.append("--release"[0...]); // TODO issue #296
130 %return zig_args.append("--release");
131131 }
132132
133 %return zig_args.append("--name"[0...]); // TODO issue #296
133 %return zig_args.append("--name");
134134 %return zig_args.append(exe.name);
135135
136136 switch (exe.target) {
137137 Target.Native => {},
138138 Target.Cross => |cross_target| {
139 %return zig_args.append("--target-arch"[0...]); // TODO issue #296
139 %return zig_args.append("--target-arch");
140140 %return zig_args.append(targetArchName(cross_target.arch));
141141
142 %return zig_args.append("--target-os"[0...]); // TODO issue #296
142 %return zig_args.append("--target-os");
143143 %return zig_args.append(targetOsName(cross_target.os));
144144
145 %return zig_args.append("--target-environ"[0...]); // TODO issue #296
145 %return zig_args.append("--target-environ");
146146 %return zig_args.append(targetEnvironName(cross_target.environ));
147147 },
148148 }
......@@ -153,11 +153,11 @@ pub const Builder = struct {
153153 const tmp_file_name = "linker.ld.tmp"; // TODO issue #298
154154 io.writeFile(tmp_file_name, script, self.allocator)
155155 %% |err| debug.panic("unable to write linker script: {}\n", @errorName(err));
156 %return zig_args.append("--linker-script"[0...]); // TODO issue #296
157 %return zig_args.append(tmp_file_name[0...]); // TODO issue #296
156 %return zig_args.append("--linker-script");
157 %return zig_args.append(tmp_file_name);
158158 },
159159 LinkerScript.Path => |path| {
160 %return zig_args.append("--linker-script"[0...]); // TODO issue #296
160 %return zig_args.append("--linker-script");
161161 %return zig_args.append(path);
162162 },
163163 }
......@@ -166,23 +166,23 @@ pub const Builder = struct {
166166 var it = exe.link_libs.iterator();
167167 while (true) {
168168 const entry = it.next() ?? break;
169 %return zig_args.append("--library"[0...]); // TODO issue #296
169 %return zig_args.append("--library");
170170 %return zig_args.append(entry.key);
171171 }
172172 }
173173
174174 for (self.include_paths.toSliceConst()) |include_path| {
175 %return zig_args.append("-isystem"[0...]); // TODO issue #296
175 %return zig_args.append("-isystem");
176176 %return zig_args.append(include_path);
177177 }
178178
179179 for (self.rpaths.toSliceConst()) |rpath| {
180 %return zig_args.append("-rpath"[0...]); // TODO issue #296
180 %return zig_args.append("-rpath");
181181 %return zig_args.append(rpath);
182182 }
183183
184184 for (self.lib_paths.toSliceConst()) |lib_path| {
185 %return zig_args.append("--library-path"[0...]); // TODO issue #296
185 %return zig_args.append("--library-path");
186186 %return zig_args.append(lib_path);
187187 }
188188
test/cases/cast.zig+5
......@@ -70,3 +70,8 @@ test "integer literal to &const int" {
7070 const x: &const i32 = 3;
7171 assert(*x == 3);
7272}
73
74test "string literal to &const []const u8" {
75 const x: &const []const u8 = "hello";
76 assert(mem.eql(u8, *x, "hello"));
77}