diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-04-06 18:07:38 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-04-06 18:07:38 -0400 |
| commit | 273cebdf4dde46f00eb177b9aa05d8dd1c0606a7 (patch) | |
| tree | d3c7f4f4bb6ceff2f1fa4e629b8a42b36cf42fcc | |
| parent | 47f58d6d029cabb46064557f8e047970a2fa52fc (diff) | |
| download | zig-273cebdf4dde46f00eb177b9aa05d8dd1c0606a7.tar.gz zig-273cebdf4dde46f00eb177b9aa05d8dd1c0606a7.zip | |
peer resolve types [N]T, [M]T as []const T
closes #125
| -rw-r--r-- | src/ir.cpp | 42 | ||||
| -rw-r--r-- | std/build.zig | 228 | ||||
| -rw-r--r-- | test/cases/cast.zig | 23 |
3 files changed, 174 insertions, 119 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index a1ccce7f2c..79f4a27914 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -5857,6 +5857,10 @@ 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]; @@ -5865,6 +5869,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod } bool any_are_pure_error = (prev_inst->value.type->id == TypeTableEntryIdPureError); bool any_are_null = (prev_inst->value.type->id == TypeTableEntryIdNullLit); + bool convert_to_const_slice = false; for (size_t i = 1; i < instruction_count; i += 1) { IrInstruction *cur_inst = instructions[i]; TypeTableEntry *cur_type = cur_inst->value.type; @@ -5932,6 +5937,34 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod } else { return ira->codegen->builtin_types.entry_invalid; } + } else if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray && + cur_type->data.array.len != prev_type->data.array.len && + types_match_const_cast_only(cur_type->data.array.child_type, prev_type->data.array.child_type)) + { + convert_to_const_slice = true; + prev_inst = cur_inst; + continue; + } else if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray && + cur_type->data.array.len != prev_type->data.array.len && + types_match_const_cast_only(prev_type->data.array.child_type, cur_type->data.array.child_type)) + { + convert_to_const_slice = true; + continue; + } else if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) && + prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const && + types_match_const_cast_only(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, + cur_type->data.array.child_type)) + { + convert_to_const_slice = false; + continue; + } else if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) && + cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const && + types_match_const_cast_only(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, + prev_type->data.array.child_type)) + { + prev_inst = cur_inst; + convert_to_const_slice = false; + continue; } else { ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("incompatible types: '%s' and '%s'", @@ -5944,7 +5977,10 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod return ira->codegen->builtin_types.entry_invalid; } } - if (any_are_pure_error && prev_inst->value.type->id != TypeTableEntryIdPureError) { + if (convert_to_const_slice) { + assert(prev_inst->value.type->id == TypeTableEntryIdArray); + return get_slice_type(ira->codegen, prev_inst->value.type->data.array.child_type, true); + } else if (any_are_pure_error && prev_inst->value.type->id != TypeTableEntryIdPureError) { if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt || prev_inst->value.type->id == TypeTableEntryIdNumLitFloat) { @@ -6038,10 +6074,6 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst } } -static bool is_slice(TypeTableEntry *type) { - return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice; -} - static bool is_container(TypeTableEntry *type) { return type->id == TypeTableEntryIdStruct || type->id == TypeTableEntryIdEnum || diff --git a/std/build.zig b/std/build.zig index 1917d1258b..8d54f01e1f 100644 --- a/std/build.zig +++ b/std/build.zig @@ -360,11 +360,11 @@ pub const Builder = struct { pub fn typeIdName(id: TypeId) -> []const u8 { return switch (id) { - TypeId.Bool => ([]const u8)("bool"), // TODO issue #125 - TypeId.Int => ([]const u8)("int"), // TODO issue #125 - TypeId.Float => ([]const u8)("float"), // TODO issue #125 - TypeId.String => ([]const u8)("string"), // TODO issue #125 - TypeId.List => ([]const u8)("list"), // TODO issue #125 + TypeId.Bool => "bool", + TypeId.Int => "int", + TypeId.Float => "float", + TypeId.String => "string", + TypeId.List => "list", }; } @@ -462,127 +462,127 @@ fn printInvocation(exe_name: []const u8, args: &const List([]const u8)) { // TODO issue #299 fn targetOsName(target_os: Os) -> []const u8 { return switch (target_os) { - Os.freestanding => ([]const u8)("freestanding"), - Os.cloudabi => ([]const u8)("cloudabi"), - Os.darwin => ([]const u8)("darwin"), - Os.dragonfly => ([]const u8)("dragonfly"), - Os.freebsd => ([]const u8)("freebsd"), - Os.ios => ([]const u8)("ios"), - Os.kfreebsd => ([]const u8)("kfreebsd"), - Os.linux => ([]const u8)("linux"), - Os.lv2 => ([]const u8)("lv2"), - Os.macosx => ([]const u8)("macosx"), - Os.netbsd => ([]const u8)("netbsd"), - Os.openbsd => ([]const u8)("openbsd"), - Os.solaris => ([]const u8)("solaris"), - Os.windows => ([]const u8)("windows"), - Os.haiku => ([]const u8)("haiku"), - Os.minix => ([]const u8)("minix"), - Os.rtems => ([]const u8)("rtems"), - Os.nacl => ([]const u8)("nacl"), - Os.cnk => ([]const u8)("cnk"), - Os.bitrig => ([]const u8)("bitrig"), - Os.aix => ([]const u8)("aix"), - Os.cuda => ([]const u8)("cuda"), - Os.nvcl => ([]const u8)("nvcl"), - Os.amdhsa => ([]const u8)("amdhsa"), - Os.ps4 => ([]const u8)("ps4"), - Os.elfiamcu => ([]const u8)("elfiamcu"), - Os.tvos => ([]const u8)("tvos"), - Os.watchos => ([]const u8)("watchos"), - Os.mesa3d => ([]const u8)("mesa3d"), + Os.freestanding => "freestanding", + Os.cloudabi => "cloudabi", + Os.darwin => "darwin", + Os.dragonfly => "dragonfly", + Os.freebsd => "freebsd", + Os.ios => "ios", + Os.kfreebsd => "kfreebsd", + Os.linux => "linux", + Os.lv2 => "lv2", + Os.macosx => "macosx", + Os.netbsd => "netbsd", + Os.openbsd => "openbsd", + Os.solaris => "solaris", + Os.windows => "windows", + Os.haiku => "haiku", + Os.minix => "minix", + Os.rtems => "rtems", + Os.nacl => "nacl", + Os.cnk => "cnk", + Os.bitrig => "bitrig", + Os.aix => "aix", + Os.cuda => "cuda", + Os.nvcl => "nvcl", + Os.amdhsa => "amdhsa", + Os.ps4 => "ps4", + Os.elfiamcu => "elfiamcu", + Os.tvos => "tvos", + Os.watchos => "watchos", + Os.mesa3d => "mesa3d", }; } // TODO issue #299 fn targetArchName(target_arch: Arch) -> []const u8 { return switch (target_arch) { - Arch.armv8_2a => ([]const u8)("armv8_2a"), - Arch.armv8_1a => ([]const u8)("armv8_1a"), - Arch.armv8 => ([]const u8)("armv8"), - Arch.armv8m_baseline => ([]const u8)("armv8m_baseline"), - Arch.armv8m_mainline => ([]const u8)("armv8m_mainline"), - Arch.armv7 => ([]const u8)("armv7"), - Arch.armv7em => ([]const u8)("armv7em"), - Arch.armv7m => ([]const u8)("armv7m"), - Arch.armv7s => ([]const u8)("armv7s"), - Arch.armv7k => ([]const u8)("armv7k"), - Arch.armv6 => ([]const u8)("armv6"), - Arch.armv6m => ([]const u8)("armv6m"), - Arch.armv6k => ([]const u8)("armv6k"), - Arch.armv6t2 => ([]const u8)("armv6t2"), - Arch.armv5 => ([]const u8)("armv5"), - Arch.armv5te => ([]const u8)("armv5te"), - Arch.armv4t => ([]const u8)("armv4t"), - Arch.armeb => ([]const u8)("armeb"), - Arch.aarch64 => ([]const u8)("aarch64"), - Arch.aarch64_be => ([]const u8)("aarch64_be"), - Arch.avr => ([]const u8)("avr"), - Arch.bpfel => ([]const u8)("bpfel"), - Arch.bpfeb => ([]const u8)("bpfeb"), - Arch.hexagon => ([]const u8)("hexagon"), - Arch.mips => ([]const u8)("mips"), - Arch.mipsel => ([]const u8)("mipsel"), - Arch.mips64 => ([]const u8)("mips64"), - Arch.mips64el => ([]const u8)("mips64el"), - Arch.msp430 => ([]const u8)("msp430"), - Arch.powerpc => ([]const u8)("powerpc"), - Arch.powerpc64 => ([]const u8)("powerpc64"), - Arch.powerpc64le => ([]const u8)("powerpc64le"), - Arch.r600 => ([]const u8)("r600"), - Arch.amdgcn => ([]const u8)("amdgcn"), - Arch.sparc => ([]const u8)("sparc"), - Arch.sparcv9 => ([]const u8)("sparcv9"), - Arch.sparcel => ([]const u8)("sparcel"), - Arch.s390x => ([]const u8)("s390x"), - Arch.tce => ([]const u8)("tce"), - Arch.thumb => ([]const u8)("thumb"), - Arch.thumbeb => ([]const u8)("thumbeb"), - Arch.i386 => ([]const u8)("i386"), - Arch.x86_64 => ([]const u8)("x86_64"), - Arch.xcore => ([]const u8)("xcore"), - Arch.nvptx => ([]const u8)("nvptx"), - Arch.nvptx64 => ([]const u8)("nvptx64"), - Arch.le32 => ([]const u8)("le32"), - Arch.le64 => ([]const u8)("le64"), - Arch.amdil => ([]const u8)("amdil"), - Arch.amdil64 => ([]const u8)("amdil64"), - Arch.hsail => ([]const u8)("hsail"), - Arch.hsail64 => ([]const u8)("hsail64"), - Arch.spir => ([]const u8)("spir"), - Arch.spir64 => ([]const u8)("spir64"), - Arch.kalimbav3 => ([]const u8)("kalimbav3"), - Arch.kalimbav4 => ([]const u8)("kalimbav4"), - Arch.kalimbav5 => ([]const u8)("kalimbav5"), - Arch.shave => ([]const u8)("shave"), - Arch.lanai => ([]const u8)("lanai"), - Arch.wasm32 => ([]const u8)("wasm32"), - Arch.wasm64 => ([]const u8)("wasm64"), - Arch.renderscript32 => ([]const u8)("renderscript32"), - Arch.renderscript64 => ([]const u8)("renderscript64"), + Arch.armv8_2a => "armv8_2a", + Arch.armv8_1a => "armv8_1a", + Arch.armv8 => "armv8", + Arch.armv8m_baseline => "armv8m_baseline", + Arch.armv8m_mainline => "armv8m_mainline", + Arch.armv7 => "armv7", + Arch.armv7em => "armv7em", + Arch.armv7m => "armv7m", + Arch.armv7s => "armv7s", + Arch.armv7k => "armv7k", + Arch.armv6 => "armv6", + Arch.armv6m => "armv6m", + Arch.armv6k => "armv6k", + Arch.armv6t2 => "armv6t2", + Arch.armv5 => "armv5", + Arch.armv5te => "armv5te", + Arch.armv4t => "armv4t", + Arch.armeb => "armeb", + Arch.aarch64 => "aarch64", + Arch.aarch64_be => "aarch64_be", + Arch.avr => "avr", + Arch.bpfel => "bpfel", + Arch.bpfeb => "bpfeb", + Arch.hexagon => "hexagon", + Arch.mips => "mips", + Arch.mipsel => "mipsel", + Arch.mips64 => "mips64", + Arch.mips64el => "mips64el", + Arch.msp430 => "msp430", + Arch.powerpc => "powerpc", + Arch.powerpc64 => "powerpc64", + Arch.powerpc64le => "powerpc64le", + Arch.r600 => "r600", + Arch.amdgcn => "amdgcn", + Arch.sparc => "sparc", + Arch.sparcv9 => "sparcv9", + Arch.sparcel => "sparcel", + Arch.s390x => "s390x", + Arch.tce => "tce", + Arch.thumb => "thumb", + Arch.thumbeb => "thumbeb", + Arch.i386 => "i386", + Arch.x86_64 => "x86_64", + Arch.xcore => "xcore", + Arch.nvptx => "nvptx", + Arch.nvptx64 => "nvptx64", + Arch.le32 => "le32", + Arch.le64 => "le64", + Arch.amdil => "amdil", + Arch.amdil64 => "amdil64", + Arch.hsail => "hsail", + Arch.hsail64 => "hsail64", + Arch.spir => "spir", + Arch.spir64 => "spir64", + Arch.kalimbav3 => "kalimbav3", + Arch.kalimbav4 => "kalimbav4", + Arch.kalimbav5 => "kalimbav5", + Arch.shave => "shave", + Arch.lanai => "lanai", + Arch.wasm32 => "wasm32", + Arch.wasm64 => "wasm64", + Arch.renderscript32 => "renderscript32", + Arch.renderscript64 => "renderscript64", }; } // TODO issue #299 fn targetEnvironName(target_environ: Environ) -> []const u8 { return switch (target_environ) { - Environ.gnu => ([]const u8)("gnu"), - Environ.gnuabi64 => ([]const u8)("gnuabi64"), - Environ.gnueabi => ([]const u8)("gnueabi"), - Environ.gnueabihf => ([]const u8)("gnueabihf"), - Environ.gnux32 => ([]const u8)("gnux32"), - Environ.code16 => ([]const u8)("code16"), - Environ.eabi => ([]const u8)("eabi"), - Environ.eabihf => ([]const u8)("eabihf"), - Environ.android => ([]const u8)("android"), - Environ.musl => ([]const u8)("musl"), - Environ.musleabi => ([]const u8)("musleabi"), - Environ.musleabihf => ([]const u8)("musleabihf"), - Environ.msvc => ([]const u8)("msvc"), - Environ.itanium => ([]const u8)("itanium"), - Environ.cygnus => ([]const u8)("cygnus"), - Environ.amdopencl => ([]const u8)("amdopencl"), - Environ.coreclr => ([]const u8)("coreclr"), + Environ.gnu => "gnu", + Environ.gnuabi64 => "gnuabi64", + Environ.gnueabi => "gnueabi", + Environ.gnueabihf => "gnueabihf", + Environ.gnux32 => "gnux32", + Environ.code16 => "code16", + Environ.eabi => "eabi", + Environ.eabihf => "eabihf", + Environ.android => "android", + Environ.musl => "musl", + Environ.musleabi => "musleabi", + Environ.musleabihf => "musleabihf", + Environ.msvc => "msvc", + Environ.itanium => "itanium", + Environ.cygnus => "cygnus", + Environ.amdopencl => "amdopencl", + Environ.coreclr => "coreclr", }; } diff --git a/test/cases/cast.zig b/test/cases/cast.zig index 12fb0d9ee4..9a97ecd623 100644 --- a/test/cases/cast.zig +++ b/test/cases/cast.zig @@ -1,4 +1,5 @@ const assert = @import("std").debug.assert; +const mem = @import("std").mem; test "intToPtrCast" { const x = isize(13); @@ -41,3 +42,25 @@ fn testCastIntToErr(err: error) { const y = error(x); assert(error.ItBroke == y); } + +test "peer resolve arrays of different size to const slice" { + assert(mem.eql(u8, boolToStr(true), "true")); + assert(mem.eql(u8, boolToStr(false), "false")); + comptime assert(mem.eql(u8, boolToStr(true), "true")); + comptime assert(mem.eql(u8, boolToStr(false), "false")); +} +fn boolToStr(b: bool) -> []const u8 { + if (b) "true" else "false" +} + + +test "peer resolve array and const slice" { + testPeerResolveArrayConstSlice(true); + comptime testPeerResolveArrayConstSlice(true); +} +fn testPeerResolveArrayConstSlice(b: bool) { + const value1 = if (b) "aoeu" else ([]const u8)("zz"); + const value2 = if (b) ([]const u8)("zz") else "aoeu"; + assert(mem.eql(u8, value1, "aoeu")); + assert(mem.eql(u8, value2, "zz")); +} |
