authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-06 18:07:38-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-06 18:07:38-04:00
log273cebdf4dde46f00eb177b9aa05d8dd1c0606a7
treed3c7f4f4bb6ceff2f1fa4e629b8a42b36cf42fcc
parent47f58d6d029cabb46064557f8e047970a2fa52fc

peer resolve types [N]T, [M]T as []const T

closes #125

3 files changed, 174 insertions(+), 119 deletions(-)

src/ir.cpp+37-5
......@@ -5857,6 +5857,10 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
58575857 return ImplicitCastMatchResultNo;
58585858}
58595859
5860static bool is_slice(TypeTableEntry *type) {
5861 return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice;
5862}
5863
58605864static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, IrInstruction **instructions, size_t instruction_count) {
58615865 assert(instruction_count >= 1);
58625866 IrInstruction *prev_inst = instructions[0];
......@@ -5865,6 +5869,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
58655869 }
58665870 bool any_are_pure_error = (prev_inst->value.type->id == TypeTableEntryIdPureError);
58675871 bool any_are_null = (prev_inst->value.type->id == TypeTableEntryIdNullLit);
5872 bool convert_to_const_slice = false;
58685873 for (size_t i = 1; i < instruction_count; i += 1) {
58695874 IrInstruction *cur_inst = instructions[i];
58705875 TypeTableEntry *cur_type = cur_inst->value.type;
......@@ -5932,6 +5937,34 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
59325937 } else {
59335938 return ira->codegen->builtin_types.entry_invalid;
59345939 }
5940 } else if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
5941 cur_type->data.array.len != prev_type->data.array.len &&
5942 types_match_const_cast_only(cur_type->data.array.child_type, prev_type->data.array.child_type))
5943 {
5944 convert_to_const_slice = true;
5945 prev_inst = cur_inst;
5946 continue;
5947 } else if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
5948 cur_type->data.array.len != prev_type->data.array.len &&
5949 types_match_const_cast_only(prev_type->data.array.child_type, cur_type->data.array.child_type))
5950 {
5951 convert_to_const_slice = true;
5952 continue;
5953 } else if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) &&
5954 prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const &&
5955 types_match_const_cast_only(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
5956 cur_type->data.array.child_type))
5957 {
5958 convert_to_const_slice = false;
5959 continue;
5960 } else if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) &&
5961 cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const &&
5962 types_match_const_cast_only(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
5963 prev_type->data.array.child_type))
5964 {
5965 prev_inst = cur_inst;
5966 convert_to_const_slice = false;
5967 continue;
59355968 } else {
59365969 ErrorMsg *msg = ir_add_error_node(ira, source_node,
59375970 buf_sprintf("incompatible types: '%s' and '%s'",
......@@ -5944,7 +5977,10 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
59445977 return ira->codegen->builtin_types.entry_invalid;
59455978 }
59465979 }
5947 if (any_are_pure_error && prev_inst->value.type->id != TypeTableEntryIdPureError) {
5980 if (convert_to_const_slice) {
5981 assert(prev_inst->value.type->id == TypeTableEntryIdArray);
5982 return get_slice_type(ira->codegen, prev_inst->value.type->data.array.child_type, true);
5983 } else if (any_are_pure_error && prev_inst->value.type->id != TypeTableEntryIdPureError) {
59485984 if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt ||
59495985 prev_inst->value.type->id == TypeTableEntryIdNumLitFloat)
59505986 {
......@@ -6038,10 +6074,6 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst
60386074 }
60396075}
60406076
6041static bool is_slice(TypeTableEntry *type) {
6042 return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice;
6043}
6044
60456077static bool is_container(TypeTableEntry *type) {
60466078 return type->id == TypeTableEntryIdStruct ||
60476079 type->id == TypeTableEntryIdEnum ||
std/build.zig+114-114
......@@ -360,11 +360,11 @@ pub const Builder = struct {
360360
361361 pub fn typeIdName(id: TypeId) -> []const u8 {
362362 return switch (id) {
363 TypeId.Bool => ([]const u8)("bool"), // TODO issue #125
364 TypeId.Int => ([]const u8)("int"), // TODO issue #125
365 TypeId.Float => ([]const u8)("float"), // TODO issue #125
366 TypeId.String => ([]const u8)("string"), // TODO issue #125
367 TypeId.List => ([]const u8)("list"), // TODO issue #125
363 TypeId.Bool => "bool",
364 TypeId.Int => "int",
365 TypeId.Float => "float",
366 TypeId.String => "string",
367 TypeId.List => "list",
368368 };
369369 }
370370
......@@ -462,127 +462,127 @@ fn printInvocation(exe_name: []const u8, args: &const List([]const u8)) {
462462// TODO issue #299
463463fn targetOsName(target_os: Os) -> []const u8 {
464464 return switch (target_os) {
465 Os.freestanding => ([]const u8)("freestanding"),
466 Os.cloudabi => ([]const u8)("cloudabi"),
467 Os.darwin => ([]const u8)("darwin"),
468 Os.dragonfly => ([]const u8)("dragonfly"),
469 Os.freebsd => ([]const u8)("freebsd"),
470 Os.ios => ([]const u8)("ios"),
471 Os.kfreebsd => ([]const u8)("kfreebsd"),
472 Os.linux => ([]const u8)("linux"),
473 Os.lv2 => ([]const u8)("lv2"),
474 Os.macosx => ([]const u8)("macosx"),
475 Os.netbsd => ([]const u8)("netbsd"),
476 Os.openbsd => ([]const u8)("openbsd"),
477 Os.solaris => ([]const u8)("solaris"),
478 Os.windows => ([]const u8)("windows"),
479 Os.haiku => ([]const u8)("haiku"),
480 Os.minix => ([]const u8)("minix"),
481 Os.rtems => ([]const u8)("rtems"),
482 Os.nacl => ([]const u8)("nacl"),
483 Os.cnk => ([]const u8)("cnk"),
484 Os.bitrig => ([]const u8)("bitrig"),
485 Os.aix => ([]const u8)("aix"),
486 Os.cuda => ([]const u8)("cuda"),
487 Os.nvcl => ([]const u8)("nvcl"),
488 Os.amdhsa => ([]const u8)("amdhsa"),
489 Os.ps4 => ([]const u8)("ps4"),
490 Os.elfiamcu => ([]const u8)("elfiamcu"),
491 Os.tvos => ([]const u8)("tvos"),
492 Os.watchos => ([]const u8)("watchos"),
493 Os.mesa3d => ([]const u8)("mesa3d"),
465 Os.freestanding => "freestanding",
466 Os.cloudabi => "cloudabi",
467 Os.darwin => "darwin",
468 Os.dragonfly => "dragonfly",
469 Os.freebsd => "freebsd",
470 Os.ios => "ios",
471 Os.kfreebsd => "kfreebsd",
472 Os.linux => "linux",
473 Os.lv2 => "lv2",
474 Os.macosx => "macosx",
475 Os.netbsd => "netbsd",
476 Os.openbsd => "openbsd",
477 Os.solaris => "solaris",
478 Os.windows => "windows",
479 Os.haiku => "haiku",
480 Os.minix => "minix",
481 Os.rtems => "rtems",
482 Os.nacl => "nacl",
483 Os.cnk => "cnk",
484 Os.bitrig => "bitrig",
485 Os.aix => "aix",
486 Os.cuda => "cuda",
487 Os.nvcl => "nvcl",
488 Os.amdhsa => "amdhsa",
489 Os.ps4 => "ps4",
490 Os.elfiamcu => "elfiamcu",
491 Os.tvos => "tvos",
492 Os.watchos => "watchos",
493 Os.mesa3d => "mesa3d",
494494 };
495495}
496496
497497// TODO issue #299
498498fn targetArchName(target_arch: Arch) -> []const u8 {
499499 return switch (target_arch) {
500 Arch.armv8_2a => ([]const u8)("armv8_2a"),
501 Arch.armv8_1a => ([]const u8)("armv8_1a"),
502 Arch.armv8 => ([]const u8)("armv8"),
503 Arch.armv8m_baseline => ([]const u8)("armv8m_baseline"),
504 Arch.armv8m_mainline => ([]const u8)("armv8m_mainline"),
505 Arch.armv7 => ([]const u8)("armv7"),
506 Arch.armv7em => ([]const u8)("armv7em"),
507 Arch.armv7m => ([]const u8)("armv7m"),
508 Arch.armv7s => ([]const u8)("armv7s"),
509 Arch.armv7k => ([]const u8)("armv7k"),
510 Arch.armv6 => ([]const u8)("armv6"),
511 Arch.armv6m => ([]const u8)("armv6m"),
512 Arch.armv6k => ([]const u8)("armv6k"),
513 Arch.armv6t2 => ([]const u8)("armv6t2"),
514 Arch.armv5 => ([]const u8)("armv5"),
515 Arch.armv5te => ([]const u8)("armv5te"),
516 Arch.armv4t => ([]const u8)("armv4t"),
517 Arch.armeb => ([]const u8)("armeb"),
518 Arch.aarch64 => ([]const u8)("aarch64"),
519 Arch.aarch64_be => ([]const u8)("aarch64_be"),
520 Arch.avr => ([]const u8)("avr"),
521 Arch.bpfel => ([]const u8)("bpfel"),
522 Arch.bpfeb => ([]const u8)("bpfeb"),
523 Arch.hexagon => ([]const u8)("hexagon"),
524 Arch.mips => ([]const u8)("mips"),
525 Arch.mipsel => ([]const u8)("mipsel"),
526 Arch.mips64 => ([]const u8)("mips64"),
527 Arch.mips64el => ([]const u8)("mips64el"),
528 Arch.msp430 => ([]const u8)("msp430"),
529 Arch.powerpc => ([]const u8)("powerpc"),
530 Arch.powerpc64 => ([]const u8)("powerpc64"),
531 Arch.powerpc64le => ([]const u8)("powerpc64le"),
532 Arch.r600 => ([]const u8)("r600"),
533 Arch.amdgcn => ([]const u8)("amdgcn"),
534 Arch.sparc => ([]const u8)("sparc"),
535 Arch.sparcv9 => ([]const u8)("sparcv9"),
536 Arch.sparcel => ([]const u8)("sparcel"),
537 Arch.s390x => ([]const u8)("s390x"),
538 Arch.tce => ([]const u8)("tce"),
539 Arch.thumb => ([]const u8)("thumb"),
540 Arch.thumbeb => ([]const u8)("thumbeb"),
541 Arch.i386 => ([]const u8)("i386"),
542 Arch.x86_64 => ([]const u8)("x86_64"),
543 Arch.xcore => ([]const u8)("xcore"),
544 Arch.nvptx => ([]const u8)("nvptx"),
545 Arch.nvptx64 => ([]const u8)("nvptx64"),
546 Arch.le32 => ([]const u8)("le32"),
547 Arch.le64 => ([]const u8)("le64"),
548 Arch.amdil => ([]const u8)("amdil"),
549 Arch.amdil64 => ([]const u8)("amdil64"),
550 Arch.hsail => ([]const u8)("hsail"),
551 Arch.hsail64 => ([]const u8)("hsail64"),
552 Arch.spir => ([]const u8)("spir"),
553 Arch.spir64 => ([]const u8)("spir64"),
554 Arch.kalimbav3 => ([]const u8)("kalimbav3"),
555 Arch.kalimbav4 => ([]const u8)("kalimbav4"),
556 Arch.kalimbav5 => ([]const u8)("kalimbav5"),
557 Arch.shave => ([]const u8)("shave"),
558 Arch.lanai => ([]const u8)("lanai"),
559 Arch.wasm32 => ([]const u8)("wasm32"),
560 Arch.wasm64 => ([]const u8)("wasm64"),
561 Arch.renderscript32 => ([]const u8)("renderscript32"),
562 Arch.renderscript64 => ([]const u8)("renderscript64"),
500 Arch.armv8_2a => "armv8_2a",
501 Arch.armv8_1a => "armv8_1a",
502 Arch.armv8 => "armv8",
503 Arch.armv8m_baseline => "armv8m_baseline",
504 Arch.armv8m_mainline => "armv8m_mainline",
505 Arch.armv7 => "armv7",
506 Arch.armv7em => "armv7em",
507 Arch.armv7m => "armv7m",
508 Arch.armv7s => "armv7s",
509 Arch.armv7k => "armv7k",
510 Arch.armv6 => "armv6",
511 Arch.armv6m => "armv6m",
512 Arch.armv6k => "armv6k",
513 Arch.armv6t2 => "armv6t2",
514 Arch.armv5 => "armv5",
515 Arch.armv5te => "armv5te",
516 Arch.armv4t => "armv4t",
517 Arch.armeb => "armeb",
518 Arch.aarch64 => "aarch64",
519 Arch.aarch64_be => "aarch64_be",
520 Arch.avr => "avr",
521 Arch.bpfel => "bpfel",
522 Arch.bpfeb => "bpfeb",
523 Arch.hexagon => "hexagon",
524 Arch.mips => "mips",
525 Arch.mipsel => "mipsel",
526 Arch.mips64 => "mips64",
527 Arch.mips64el => "mips64el",
528 Arch.msp430 => "msp430",
529 Arch.powerpc => "powerpc",
530 Arch.powerpc64 => "powerpc64",
531 Arch.powerpc64le => "powerpc64le",
532 Arch.r600 => "r600",
533 Arch.amdgcn => "amdgcn",
534 Arch.sparc => "sparc",
535 Arch.sparcv9 => "sparcv9",
536 Arch.sparcel => "sparcel",
537 Arch.s390x => "s390x",
538 Arch.tce => "tce",
539 Arch.thumb => "thumb",
540 Arch.thumbeb => "thumbeb",
541 Arch.i386 => "i386",
542 Arch.x86_64 => "x86_64",
543 Arch.xcore => "xcore",
544 Arch.nvptx => "nvptx",
545 Arch.nvptx64 => "nvptx64",
546 Arch.le32 => "le32",
547 Arch.le64 => "le64",
548 Arch.amdil => "amdil",
549 Arch.amdil64 => "amdil64",
550 Arch.hsail => "hsail",
551 Arch.hsail64 => "hsail64",
552 Arch.spir => "spir",
553 Arch.spir64 => "spir64",
554 Arch.kalimbav3 => "kalimbav3",
555 Arch.kalimbav4 => "kalimbav4",
556 Arch.kalimbav5 => "kalimbav5",
557 Arch.shave => "shave",
558 Arch.lanai => "lanai",
559 Arch.wasm32 => "wasm32",
560 Arch.wasm64 => "wasm64",
561 Arch.renderscript32 => "renderscript32",
562 Arch.renderscript64 => "renderscript64",
563563 };
564564}
565565
566566// TODO issue #299
567567fn targetEnvironName(target_environ: Environ) -> []const u8 {
568568 return switch (target_environ) {
569 Environ.gnu => ([]const u8)("gnu"),
570 Environ.gnuabi64 => ([]const u8)("gnuabi64"),
571 Environ.gnueabi => ([]const u8)("gnueabi"),
572 Environ.gnueabihf => ([]const u8)("gnueabihf"),
573 Environ.gnux32 => ([]const u8)("gnux32"),
574 Environ.code16 => ([]const u8)("code16"),
575 Environ.eabi => ([]const u8)("eabi"),
576 Environ.eabihf => ([]const u8)("eabihf"),
577 Environ.android => ([]const u8)("android"),
578 Environ.musl => ([]const u8)("musl"),
579 Environ.musleabi => ([]const u8)("musleabi"),
580 Environ.musleabihf => ([]const u8)("musleabihf"),
581 Environ.msvc => ([]const u8)("msvc"),
582 Environ.itanium => ([]const u8)("itanium"),
583 Environ.cygnus => ([]const u8)("cygnus"),
584 Environ.amdopencl => ([]const u8)("amdopencl"),
585 Environ.coreclr => ([]const u8)("coreclr"),
569 Environ.gnu => "gnu",
570 Environ.gnuabi64 => "gnuabi64",
571 Environ.gnueabi => "gnueabi",
572 Environ.gnueabihf => "gnueabihf",
573 Environ.gnux32 => "gnux32",
574 Environ.code16 => "code16",
575 Environ.eabi => "eabi",
576 Environ.eabihf => "eabihf",
577 Environ.android => "android",
578 Environ.musl => "musl",
579 Environ.musleabi => "musleabi",
580 Environ.musleabihf => "musleabihf",
581 Environ.msvc => "msvc",
582 Environ.itanium => "itanium",
583 Environ.cygnus => "cygnus",
584 Environ.amdopencl => "amdopencl",
585 Environ.coreclr => "coreclr",
586586 };
587587}
588588
test/cases/cast.zig+23
......@@ -1,4 +1,5 @@
11const assert = @import("std").debug.assert;
2const mem = @import("std").mem;
23
34test "intToPtrCast" {
45 const x = isize(13);
......@@ -41,3 +42,25 @@ fn testCastIntToErr(err: error) {
4142 const y = error(x);
4243 assert(error.ItBroke == y);
4344}
45
46test "peer resolve arrays of different size to const slice" {
47 assert(mem.eql(u8, boolToStr(true), "true"));
48 assert(mem.eql(u8, boolToStr(false), "false"));
49 comptime assert(mem.eql(u8, boolToStr(true), "true"));
50 comptime assert(mem.eql(u8, boolToStr(false), "false"));
51}
52fn boolToStr(b: bool) -> []const u8 {
53 if (b) "true" else "false"
54}
55
56
57test "peer resolve array and const slice" {
58 testPeerResolveArrayConstSlice(true);
59 comptime testPeerResolveArrayConstSlice(true);
60}
61fn testPeerResolveArrayConstSlice(b: bool) {
62 const value1 = if (b) "aoeu" else ([]const u8)("zz");
63 const value2 = if (b) ([]const u8)("zz") else "aoeu";
64 assert(mem.eql(u8, value1, "aoeu"));
65 assert(mem.eql(u8, value2, "zz"));
66}