Commit 47f06be369

Andrew Kelley <andrew@ziglang.org>
2019-11-20 02:29:08
string literals are now null terminated
this also deletes C string literals from the language, and then makes the std lib changes and compiler changes necessary to get the behavior tests and std lib tests passing again.
1 parent 21f344b
lib/std/crypto/x25519.zig
@@ -610,8 +610,8 @@ test "x25519 rfc7748 vector2" {
 }
 
 test "x25519 rfc7748 one iteration" {
-    const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
-    const expected_output = "\x42\x2c\x8e\x7a\x62\x27\xd7\xbc\xa1\x35\x0b\x3e\x2b\xb7\x27\x9f\x78\x97\xb8\x7b\xb6\x85\x4b\x78\x3c\x60\xe8\x03\x11\xae\x30\x79";
+    const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*;
+    const expected_output = "\x42\x2c\x8e\x7a\x62\x27\xd7\xbc\xa1\x35\x0b\x3e\x2b\xb7\x27\x9f\x78\x97\xb8\x7b\xb6\x85\x4b\x78\x3c\x60\xe8\x03\x11\xae\x30\x79".*;
 
     var k: [32]u8 = initial_value;
     var u: [32]u8 = initial_value;
@@ -634,8 +634,8 @@ test "x25519 rfc7748 1,000 iterations" {
         return error.SkipZigTest;
     }
 
-    const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
-    const expected_output = "\x68\x4c\xf5\x9b\xa8\x33\x09\x55\x28\x00\xef\x56\x6f\x2f\x4d\x3c\x1c\x38\x87\xc4\x93\x60\xe3\x87\x5f\x2e\xb9\x4d\x99\x53\x2c\x51";
+    const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*;
+    const expected_output = "\x68\x4c\xf5\x9b\xa8\x33\x09\x55\x28\x00\xef\x56\x6f\x2f\x4d\x3c\x1c\x38\x87\xc4\x93\x60\xe3\x87\x5f\x2e\xb9\x4d\x99\x53\x2c\x51".*;
 
     var k: [32]u8 = initial_value;
     var u: [32]u8 = initial_value;
@@ -657,8 +657,8 @@ test "x25519 rfc7748 1,000,000 iterations" {
         return error.SkipZigTest;
     }
 
-    const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
-    const expected_output = "\x7c\x39\x11\xe0\xab\x25\x86\xfd\x86\x44\x97\x29\x7e\x57\x5e\x6f\x3b\xc6\x01\xc0\x88\x3c\x30\xdf\x5f\x4d\xd2\xd2\x4f\x66\x54\x24";
+    const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*;
+    const expected_output = "\x7c\x39\x11\xe0\xab\x25\x86\xfd\x86\x44\x97\x29\x7e\x57\x5e\x6f\x3b\xc6\x01\xc0\x88\x3c\x30\xdf\x5f\x4d\xd2\xd2\x4f\x66\x54\x24".*;
 
     var k: [32]u8 = initial_value;
     var u: [32]u8 = initial_value;
lib/std/fs/file.zig
@@ -172,7 +172,7 @@ pub const File = struct {
         if (self.isTty()) {
             if (self.handle == os.STDOUT_FILENO or self.handle == os.STDERR_FILENO) {
                 // Use getenvC to workaround https://github.com/ziglang/zig/issues/3511
-                if (os.getenvC(c"TERM")) |term| {
+                if (os.getenvC("TERM")) |term| {
                     if (std.mem.eql(u8, term, "dumb"))
                         return false;
                 }
lib/std/fs/path.zig
@@ -394,7 +394,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
     }
 
     // determine which disk designator we will result with, if any
-    var result_drive_buf = "_:";
+    var result_drive_buf = "_:".*;
     var result_disk_designator: []const u8 = "";
     var have_drive_kind = WindowsPath.Kind.None;
     var have_abs_path = false;
lib/std/hash/siphash.zig
@@ -202,70 +202,70 @@ const test_key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x
 
 test "siphash64-2-4 sanity" {
     const vectors = [_][8]u8{
-        "\x31\x0e\x0e\xdd\x47\xdb\x6f\x72", // ""
-        "\xfd\x67\xdc\x93\xc5\x39\xf8\x74", // "\x00"
-        "\x5a\x4f\xa9\xd9\x09\x80\x6c\x0d", // "\x00\x01" ... etc
-        "\x2d\x7e\xfb\xd7\x96\x66\x67\x85",
-        "\xb7\x87\x71\x27\xe0\x94\x27\xcf",
-        "\x8d\xa6\x99\xcd\x64\x55\x76\x18",
-        "\xce\xe3\xfe\x58\x6e\x46\xc9\xcb",
-        "\x37\xd1\x01\x8b\xf5\x00\x02\xab",
-        "\x62\x24\x93\x9a\x79\xf5\xf5\x93",
-        "\xb0\xe4\xa9\x0b\xdf\x82\x00\x9e",
-        "\xf3\xb9\xdd\x94\xc5\xbb\x5d\x7a",
-        "\xa7\xad\x6b\x22\x46\x2f\xb3\xf4",
-        "\xfb\xe5\x0e\x86\xbc\x8f\x1e\x75",
-        "\x90\x3d\x84\xc0\x27\x56\xea\x14",
-        "\xee\xf2\x7a\x8e\x90\xca\x23\xf7",
-        "\xe5\x45\xbe\x49\x61\xca\x29\xa1",
-        "\xdb\x9b\xc2\x57\x7f\xcc\x2a\x3f",
-        "\x94\x47\xbe\x2c\xf5\xe9\x9a\x69",
-        "\x9c\xd3\x8d\x96\xf0\xb3\xc1\x4b",
-        "\xbd\x61\x79\xa7\x1d\xc9\x6d\xbb",
-        "\x98\xee\xa2\x1a\xf2\x5c\xd6\xbe",
-        "\xc7\x67\x3b\x2e\xb0\xcb\xf2\xd0",
-        "\x88\x3e\xa3\xe3\x95\x67\x53\x93",
-        "\xc8\xce\x5c\xcd\x8c\x03\x0c\xa8",
-        "\x94\xaf\x49\xf6\xc6\x50\xad\xb8",
-        "\xea\xb8\x85\x8a\xde\x92\xe1\xbc",
-        "\xf3\x15\xbb\x5b\xb8\x35\xd8\x17",
-        "\xad\xcf\x6b\x07\x63\x61\x2e\x2f",
-        "\xa5\xc9\x1d\xa7\xac\xaa\x4d\xde",
-        "\x71\x65\x95\x87\x66\x50\xa2\xa6",
-        "\x28\xef\x49\x5c\x53\xa3\x87\xad",
-        "\x42\xc3\x41\xd8\xfa\x92\xd8\x32",
-        "\xce\x7c\xf2\x72\x2f\x51\x27\x71",
-        "\xe3\x78\x59\xf9\x46\x23\xf3\xa7",
-        "\x38\x12\x05\xbb\x1a\xb0\xe0\x12",
-        "\xae\x97\xa1\x0f\xd4\x34\xe0\x15",
-        "\xb4\xa3\x15\x08\xbe\xff\x4d\x31",
-        "\x81\x39\x62\x29\xf0\x90\x79\x02",
-        "\x4d\x0c\xf4\x9e\xe5\xd4\xdc\xca",
-        "\x5c\x73\x33\x6a\x76\xd8\xbf\x9a",
-        "\xd0\xa7\x04\x53\x6b\xa9\x3e\x0e",
-        "\x92\x59\x58\xfc\xd6\x42\x0c\xad",
-        "\xa9\x15\xc2\x9b\xc8\x06\x73\x18",
-        "\x95\x2b\x79\xf3\xbc\x0a\xa6\xd4",
-        "\xf2\x1d\xf2\xe4\x1d\x45\x35\xf9",
-        "\x87\x57\x75\x19\x04\x8f\x53\xa9",
-        "\x10\xa5\x6c\xf5\xdf\xcd\x9a\xdb",
-        "\xeb\x75\x09\x5c\xcd\x98\x6c\xd0",
-        "\x51\xa9\xcb\x9e\xcb\xa3\x12\xe6",
-        "\x96\xaf\xad\xfc\x2c\xe6\x66\xc7",
-        "\x72\xfe\x52\x97\x5a\x43\x64\xee",
-        "\x5a\x16\x45\xb2\x76\xd5\x92\xa1",
-        "\xb2\x74\xcb\x8e\xbf\x87\x87\x0a",
-        "\x6f\x9b\xb4\x20\x3d\xe7\xb3\x81",
-        "\xea\xec\xb2\xa3\x0b\x22\xa8\x7f",
-        "\x99\x24\xa4\x3c\xc1\x31\x57\x24",
-        "\xbd\x83\x8d\x3a\xaf\xbf\x8d\xb7",
-        "\x0b\x1a\x2a\x32\x65\xd5\x1a\xea",
-        "\x13\x50\x79\xa3\x23\x1c\xe6\x60",
-        "\x93\x2b\x28\x46\xe4\xd7\x06\x66",
-        "\xe1\x91\x5f\x5c\xb1\xec\xa4\x6c",
-        "\xf3\x25\x96\x5c\xa1\x6d\x62\x9f",
-        "\x57\x5f\xf2\x8e\x60\x38\x1b\xe5",
-        "\x72\x45\x06\xeb\x4c\x32\x8a\x95",
+        "\x31\x0e\x0e\xdd\x47\xdb\x6f\x72".*, // ""
+        "\xfd\x67\xdc\x93\xc5\x39\xf8\x74".*, // "\x00"
+        "\x5a\x4f\xa9\xd9\x09\x80\x6c\x0d".*, // "\x00\x01" ... etc
+        "\x2d\x7e\xfb\xd7\x96\x66\x67\x85".*,
+        "\xb7\x87\x71\x27\xe0\x94\x27\xcf".*,
+        "\x8d\xa6\x99\xcd\x64\x55\x76\x18".*,
+        "\xce\xe3\xfe\x58\x6e\x46\xc9\xcb".*,
+        "\x37\xd1\x01\x8b\xf5\x00\x02\xab".*,
+        "\x62\x24\x93\x9a\x79\xf5\xf5\x93".*,
+        "\xb0\xe4\xa9\x0b\xdf\x82\x00\x9e".*,
+        "\xf3\xb9\xdd\x94\xc5\xbb\x5d\x7a".*,
+        "\xa7\xad\x6b\x22\x46\x2f\xb3\xf4".*,
+        "\xfb\xe5\x0e\x86\xbc\x8f\x1e\x75".*,
+        "\x90\x3d\x84\xc0\x27\x56\xea\x14".*,
+        "\xee\xf2\x7a\x8e\x90\xca\x23\xf7".*,
+        "\xe5\x45\xbe\x49\x61\xca\x29\xa1".*,
+        "\xdb\x9b\xc2\x57\x7f\xcc\x2a\x3f".*,
+        "\x94\x47\xbe\x2c\xf5\xe9\x9a\x69".*,
+        "\x9c\xd3\x8d\x96\xf0\xb3\xc1\x4b".*,
+        "\xbd\x61\x79\xa7\x1d\xc9\x6d\xbb".*,
+        "\x98\xee\xa2\x1a\xf2\x5c\xd6\xbe".*,
+        "\xc7\x67\x3b\x2e\xb0\xcb\xf2\xd0".*,
+        "\x88\x3e\xa3\xe3\x95\x67\x53\x93".*,
+        "\xc8\xce\x5c\xcd\x8c\x03\x0c\xa8".*,
+        "\x94\xaf\x49\xf6\xc6\x50\xad\xb8".*,
+        "\xea\xb8\x85\x8a\xde\x92\xe1\xbc".*,
+        "\xf3\x15\xbb\x5b\xb8\x35\xd8\x17".*,
+        "\xad\xcf\x6b\x07\x63\x61\x2e\x2f".*,
+        "\xa5\xc9\x1d\xa7\xac\xaa\x4d\xde".*,
+        "\x71\x65\x95\x87\x66\x50\xa2\xa6".*,
+        "\x28\xef\x49\x5c\x53\xa3\x87\xad".*,
+        "\x42\xc3\x41\xd8\xfa\x92\xd8\x32".*,
+        "\xce\x7c\xf2\x72\x2f\x51\x27\x71".*,
+        "\xe3\x78\x59\xf9\x46\x23\xf3\xa7".*,
+        "\x38\x12\x05\xbb\x1a\xb0\xe0\x12".*,
+        "\xae\x97\xa1\x0f\xd4\x34\xe0\x15".*,
+        "\xb4\xa3\x15\x08\xbe\xff\x4d\x31".*,
+        "\x81\x39\x62\x29\xf0\x90\x79\x02".*,
+        "\x4d\x0c\xf4\x9e\xe5\xd4\xdc\xca".*,
+        "\x5c\x73\x33\x6a\x76\xd8\xbf\x9a".*,
+        "\xd0\xa7\x04\x53\x6b\xa9\x3e\x0e".*,
+        "\x92\x59\x58\xfc\xd6\x42\x0c\xad".*,
+        "\xa9\x15\xc2\x9b\xc8\x06\x73\x18".*,
+        "\x95\x2b\x79\xf3\xbc\x0a\xa6\xd4".*,
+        "\xf2\x1d\xf2\xe4\x1d\x45\x35\xf9".*,
+        "\x87\x57\x75\x19\x04\x8f\x53\xa9".*,
+        "\x10\xa5\x6c\xf5\xdf\xcd\x9a\xdb".*,
+        "\xeb\x75\x09\x5c\xcd\x98\x6c\xd0".*,
+        "\x51\xa9\xcb\x9e\xcb\xa3\x12\xe6".*,
+        "\x96\xaf\xad\xfc\x2c\xe6\x66\xc7".*,
+        "\x72\xfe\x52\x97\x5a\x43\x64\xee".*,
+        "\x5a\x16\x45\xb2\x76\xd5\x92\xa1".*,
+        "\xb2\x74\xcb\x8e\xbf\x87\x87\x0a".*,
+        "\x6f\x9b\xb4\x20\x3d\xe7\xb3\x81".*,
+        "\xea\xec\xb2\xa3\x0b\x22\xa8\x7f".*,
+        "\x99\x24\xa4\x3c\xc1\x31\x57\x24".*,
+        "\xbd\x83\x8d\x3a\xaf\xbf\x8d\xb7".*,
+        "\x0b\x1a\x2a\x32\x65\xd5\x1a\xea".*,
+        "\x13\x50\x79\xa3\x23\x1c\xe6\x60".*,
+        "\x93\x2b\x28\x46\xe4\xd7\x06\x66".*,
+        "\xe1\x91\x5f\x5c\xb1\xec\xa4\x6c".*,
+        "\xf3\x25\x96\x5c\xa1\x6d\x62\x9f".*,
+        "\x57\x5f\xf2\x8e\x60\x38\x1b\xe5".*,
+        "\x72\x45\x06\xeb\x4c\x32\x8a\x95".*,
     };
 
     const siphash = SipHash64(2, 4);
@@ -281,70 +281,70 @@ test "siphash64-2-4 sanity" {
 
 test "siphash128-2-4 sanity" {
     const vectors = [_][16]u8{
-        "\xa3\x81\x7f\x04\xba\x25\xa8\xe6\x6d\xf6\x72\x14\xc7\x55\x02\x93",
-        "\xda\x87\xc1\xd8\x6b\x99\xaf\x44\x34\x76\x59\x11\x9b\x22\xfc\x45",
-        "\x81\x77\x22\x8d\xa4\xa4\x5d\xc7\xfc\xa3\x8b\xde\xf6\x0a\xff\xe4",
-        "\x9c\x70\xb6\x0c\x52\x67\xa9\x4e\x5f\x33\xb6\xb0\x29\x85\xed\x51",
-        "\xf8\x81\x64\xc1\x2d\x9c\x8f\xaf\x7d\x0f\x6e\x7c\x7b\xcd\x55\x79",
-        "\x13\x68\x87\x59\x80\x77\x6f\x88\x54\x52\x7a\x07\x69\x0e\x96\x27",
-        "\x14\xee\xca\x33\x8b\x20\x86\x13\x48\x5e\xa0\x30\x8f\xd7\xa1\x5e",
-        "\xa1\xf1\xeb\xbe\xd8\xdb\xc1\x53\xc0\xb8\x4a\xa6\x1f\xf0\x82\x39",
-        "\x3b\x62\xa9\xba\x62\x58\xf5\x61\x0f\x83\xe2\x64\xf3\x14\x97\xb4",
-        "\x26\x44\x99\x06\x0a\xd9\xba\xab\xc4\x7f\x8b\x02\xbb\x6d\x71\xed",
-        "\x00\x11\x0d\xc3\x78\x14\x69\x56\xc9\x54\x47\xd3\xf3\xd0\xfb\xba",
-        "\x01\x51\xc5\x68\x38\x6b\x66\x77\xa2\xb4\xdc\x6f\x81\xe5\xdc\x18",
-        "\xd6\x26\xb2\x66\x90\x5e\xf3\x58\x82\x63\x4d\xf6\x85\x32\xc1\x25",
-        "\x98\x69\xe2\x47\xe9\xc0\x8b\x10\xd0\x29\x93\x4f\xc4\xb9\x52\xf7",
-        "\x31\xfc\xef\xac\x66\xd7\xde\x9c\x7e\xc7\x48\x5f\xe4\x49\x49\x02",
-        "\x54\x93\xe9\x99\x33\xb0\xa8\x11\x7e\x08\xec\x0f\x97\xcf\xc3\xd9",
-        "\x6e\xe2\xa4\xca\x67\xb0\x54\xbb\xfd\x33\x15\xbf\x85\x23\x05\x77",
-        "\x47\x3d\x06\xe8\x73\x8d\xb8\x98\x54\xc0\x66\xc4\x7a\xe4\x77\x40",
-        "\xa4\x26\xe5\xe4\x23\xbf\x48\x85\x29\x4d\xa4\x81\xfe\xae\xf7\x23",
-        "\x78\x01\x77\x31\xcf\x65\xfa\xb0\x74\xd5\x20\x89\x52\x51\x2e\xb1",
-        "\x9e\x25\xfc\x83\x3f\x22\x90\x73\x3e\x93\x44\xa5\xe8\x38\x39\xeb",
-        "\x56\x8e\x49\x5a\xbe\x52\x5a\x21\x8a\x22\x14\xcd\x3e\x07\x1d\x12",
-        "\x4a\x29\xb5\x45\x52\xd1\x6b\x9a\x46\x9c\x10\x52\x8e\xff\x0a\xae",
-        "\xc9\xd1\x84\xdd\xd5\xa9\xf5\xe0\xcf\x8c\xe2\x9a\x9a\xbf\x69\x1c",
-        "\x2d\xb4\x79\xae\x78\xbd\x50\xd8\x88\x2a\x8a\x17\x8a\x61\x32\xad",
-        "\x8e\xce\x5f\x04\x2d\x5e\x44\x7b\x50\x51\xb9\xea\xcb\x8d\x8f\x6f",
-        "\x9c\x0b\x53\xb4\xb3\xc3\x07\xe8\x7e\xae\xe0\x86\x78\x14\x1f\x66",
-        "\xab\xf2\x48\xaf\x69\xa6\xea\xe4\xbf\xd3\xeb\x2f\x12\x9e\xeb\x94",
-        "\x06\x64\xda\x16\x68\x57\x4b\x88\xb9\x35\xf3\x02\x73\x58\xae\xf4",
-        "\xaa\x4b\x9d\xc4\xbf\x33\x7d\xe9\x0c\xd4\xfd\x3c\x46\x7c\x6a\xb7",
-        "\xea\x5c\x7f\x47\x1f\xaf\x6b\xde\x2b\x1a\xd7\xd4\x68\x6d\x22\x87",
-        "\x29\x39\xb0\x18\x32\x23\xfa\xfc\x17\x23\xde\x4f\x52\xc4\x3d\x35",
-        "\x7c\x39\x56\xca\x5e\xea\xfc\x3e\x36\x3e\x9d\x55\x65\x46\xeb\x68",
-        "\x77\xc6\x07\x71\x46\xf0\x1c\x32\xb6\xb6\x9d\x5f\x4e\xa9\xff\xcf",
-        "\x37\xa6\x98\x6c\xb8\x84\x7e\xdf\x09\x25\xf0\xf1\x30\x9b\x54\xde",
-        "\xa7\x05\xf0\xe6\x9d\xa9\xa8\xf9\x07\x24\x1a\x2e\x92\x3c\x8c\xc8",
-        "\x3d\xc4\x7d\x1f\x29\xc4\x48\x46\x1e\x9e\x76\xed\x90\x4f\x67\x11",
-        "\x0d\x62\xbf\x01\xe6\xfc\x0e\x1a\x0d\x3c\x47\x51\xc5\xd3\x69\x2b",
-        "\x8c\x03\x46\x8b\xca\x7c\x66\x9e\xe4\xfd\x5e\x08\x4b\xbe\xe7\xb5",
-        "\x52\x8a\x5b\xb9\x3b\xaf\x2c\x9c\x44\x73\xcc\xe5\xd0\xd2\x2b\xd9",
-        "\xdf\x6a\x30\x1e\x95\xc9\x5d\xad\x97\xae\x0c\xc8\xc6\x91\x3b\xd8",
-        "\x80\x11\x89\x90\x2c\x85\x7f\x39\xe7\x35\x91\x28\x5e\x70\xb6\xdb",
-        "\xe6\x17\x34\x6a\xc9\xc2\x31\xbb\x36\x50\xae\x34\xcc\xca\x0c\x5b",
-        "\x27\xd9\x34\x37\xef\xb7\x21\xaa\x40\x18\x21\xdc\xec\x5a\xdf\x89",
-        "\x89\x23\x7d\x9d\xed\x9c\x5e\x78\xd8\xb1\xc9\xb1\x66\xcc\x73\x42",
-        "\x4a\x6d\x80\x91\xbf\x5e\x7d\x65\x11\x89\xfa\x94\xa2\x50\xb1\x4c",
-        "\x0e\x33\xf9\x60\x55\xe7\xae\x89\x3f\xfc\x0e\x3d\xcf\x49\x29\x02",
-        "\xe6\x1c\x43\x2b\x72\x0b\x19\xd1\x8e\xc8\xd8\x4b\xdc\x63\x15\x1b",
-        "\xf7\xe5\xae\xf5\x49\xf7\x82\xcf\x37\x90\x55\xa6\x08\x26\x9b\x16",
-        "\x43\x8d\x03\x0f\xd0\xb7\xa5\x4f\xa8\x37\xf2\xad\x20\x1a\x64\x03",
-        "\xa5\x90\xd3\xee\x4f\xbf\x04\xe3\x24\x7e\x0d\x27\xf2\x86\x42\x3f",
-        "\x5f\xe2\xc1\xa1\x72\xfe\x93\xc4\xb1\x5c\xd3\x7c\xae\xf9\xf5\x38",
-        "\x2c\x97\x32\x5c\xbd\x06\xb3\x6e\xb2\x13\x3d\xd0\x8b\x3a\x01\x7c",
-        "\x92\xc8\x14\x22\x7a\x6b\xca\x94\x9f\xf0\x65\x9f\x00\x2a\xd3\x9e",
-        "\xdc\xe8\x50\x11\x0b\xd8\x32\x8c\xfb\xd5\x08\x41\xd6\x91\x1d\x87",
-        "\x67\xf1\x49\x84\xc7\xda\x79\x12\x48\xe3\x2b\xb5\x92\x25\x83\xda",
-        "\x19\x38\xf2\xcf\x72\xd5\x4e\xe9\x7e\x94\x16\x6f\xa9\x1d\x2a\x36",
-        "\x74\x48\x1e\x96\x46\xed\x49\xfe\x0f\x62\x24\x30\x16\x04\x69\x8e",
-        "\x57\xfc\xa5\xde\x98\xa9\xd6\xd8\x00\x64\x38\xd0\x58\x3d\x8a\x1d",
-        "\x9f\xec\xde\x1c\xef\xdc\x1c\xbe\xd4\x76\x36\x74\xd9\x57\x53\x59",
-        "\xe3\x04\x0c\x00\xeb\x28\xf1\x53\x66\xca\x73\xcb\xd8\x72\xe7\x40",
-        "\x76\x97\x00\x9a\x6a\x83\x1d\xfe\xcc\xa9\x1c\x59\x93\x67\x0f\x7a",
-        "\x58\x53\x54\x23\x21\xf5\x67\xa0\x05\xd5\x47\xa4\xf0\x47\x59\xbd",
-        "\x51\x50\xd1\x77\x2f\x50\x83\x4a\x50\x3e\x06\x9a\x97\x3f\xbd\x7c",
+        "\xa3\x81\x7f\x04\xba\x25\xa8\xe6\x6d\xf6\x72\x14\xc7\x55\x02\x93".*,
+        "\xda\x87\xc1\xd8\x6b\x99\xaf\x44\x34\x76\x59\x11\x9b\x22\xfc\x45".*,
+        "\x81\x77\x22\x8d\xa4\xa4\x5d\xc7\xfc\xa3\x8b\xde\xf6\x0a\xff\xe4".*,
+        "\x9c\x70\xb6\x0c\x52\x67\xa9\x4e\x5f\x33\xb6\xb0\x29\x85\xed\x51".*,
+        "\xf8\x81\x64\xc1\x2d\x9c\x8f\xaf\x7d\x0f\x6e\x7c\x7b\xcd\x55\x79".*,
+        "\x13\x68\x87\x59\x80\x77\x6f\x88\x54\x52\x7a\x07\x69\x0e\x96\x27".*,
+        "\x14\xee\xca\x33\x8b\x20\x86\x13\x48\x5e\xa0\x30\x8f\xd7\xa1\x5e".*,
+        "\xa1\xf1\xeb\xbe\xd8\xdb\xc1\x53\xc0\xb8\x4a\xa6\x1f\xf0\x82\x39".*,
+        "\x3b\x62\xa9\xba\x62\x58\xf5\x61\x0f\x83\xe2\x64\xf3\x14\x97\xb4".*,
+        "\x26\x44\x99\x06\x0a\xd9\xba\xab\xc4\x7f\x8b\x02\xbb\x6d\x71\xed".*,
+        "\x00\x11\x0d\xc3\x78\x14\x69\x56\xc9\x54\x47\xd3\xf3\xd0\xfb\xba".*,
+        "\x01\x51\xc5\x68\x38\x6b\x66\x77\xa2\xb4\xdc\x6f\x81\xe5\xdc\x18".*,
+        "\xd6\x26\xb2\x66\x90\x5e\xf3\x58\x82\x63\x4d\xf6\x85\x32\xc1\x25".*,
+        "\x98\x69\xe2\x47\xe9\xc0\x8b\x10\xd0\x29\x93\x4f\xc4\xb9\x52\xf7".*,
+        "\x31\xfc\xef\xac\x66\xd7\xde\x9c\x7e\xc7\x48\x5f\xe4\x49\x49\x02".*,
+        "\x54\x93\xe9\x99\x33\xb0\xa8\x11\x7e\x08\xec\x0f\x97\xcf\xc3\xd9".*,
+        "\x6e\xe2\xa4\xca\x67\xb0\x54\xbb\xfd\x33\x15\xbf\x85\x23\x05\x77".*,
+        "\x47\x3d\x06\xe8\x73\x8d\xb8\x98\x54\xc0\x66\xc4\x7a\xe4\x77\x40".*,
+        "\xa4\x26\xe5\xe4\x23\xbf\x48\x85\x29\x4d\xa4\x81\xfe\xae\xf7\x23".*,
+        "\x78\x01\x77\x31\xcf\x65\xfa\xb0\x74\xd5\x20\x89\x52\x51\x2e\xb1".*,
+        "\x9e\x25\xfc\x83\x3f\x22\x90\x73\x3e\x93\x44\xa5\xe8\x38\x39\xeb".*,
+        "\x56\x8e\x49\x5a\xbe\x52\x5a\x21\x8a\x22\x14\xcd\x3e\x07\x1d\x12".*,
+        "\x4a\x29\xb5\x45\x52\xd1\x6b\x9a\x46\x9c\x10\x52\x8e\xff\x0a\xae".*,
+        "\xc9\xd1\x84\xdd\xd5\xa9\xf5\xe0\xcf\x8c\xe2\x9a\x9a\xbf\x69\x1c".*,
+        "\x2d\xb4\x79\xae\x78\xbd\x50\xd8\x88\x2a\x8a\x17\x8a\x61\x32\xad".*,
+        "\x8e\xce\x5f\x04\x2d\x5e\x44\x7b\x50\x51\xb9\xea\xcb\x8d\x8f\x6f".*,
+        "\x9c\x0b\x53\xb4\xb3\xc3\x07\xe8\x7e\xae\xe0\x86\x78\x14\x1f\x66".*,
+        "\xab\xf2\x48\xaf\x69\xa6\xea\xe4\xbf\xd3\xeb\x2f\x12\x9e\xeb\x94".*,
+        "\x06\x64\xda\x16\x68\x57\x4b\x88\xb9\x35\xf3\x02\x73\x58\xae\xf4".*,
+        "\xaa\x4b\x9d\xc4\xbf\x33\x7d\xe9\x0c\xd4\xfd\x3c\x46\x7c\x6a\xb7".*,
+        "\xea\x5c\x7f\x47\x1f\xaf\x6b\xde\x2b\x1a\xd7\xd4\x68\x6d\x22\x87".*,
+        "\x29\x39\xb0\x18\x32\x23\xfa\xfc\x17\x23\xde\x4f\x52\xc4\x3d\x35".*,
+        "\x7c\x39\x56\xca\x5e\xea\xfc\x3e\x36\x3e\x9d\x55\x65\x46\xeb\x68".*,
+        "\x77\xc6\x07\x71\x46\xf0\x1c\x32\xb6\xb6\x9d\x5f\x4e\xa9\xff\xcf".*,
+        "\x37\xa6\x98\x6c\xb8\x84\x7e\xdf\x09\x25\xf0\xf1\x30\x9b\x54\xde".*,
+        "\xa7\x05\xf0\xe6\x9d\xa9\xa8\xf9\x07\x24\x1a\x2e\x92\x3c\x8c\xc8".*,
+        "\x3d\xc4\x7d\x1f\x29\xc4\x48\x46\x1e\x9e\x76\xed\x90\x4f\x67\x11".*,
+        "\x0d\x62\xbf\x01\xe6\xfc\x0e\x1a\x0d\x3c\x47\x51\xc5\xd3\x69\x2b".*,
+        "\x8c\x03\x46\x8b\xca\x7c\x66\x9e\xe4\xfd\x5e\x08\x4b\xbe\xe7\xb5".*,
+        "\x52\x8a\x5b\xb9\x3b\xaf\x2c\x9c\x44\x73\xcc\xe5\xd0\xd2\x2b\xd9".*,
+        "\xdf\x6a\x30\x1e\x95\xc9\x5d\xad\x97\xae\x0c\xc8\xc6\x91\x3b\xd8".*,
+        "\x80\x11\x89\x90\x2c\x85\x7f\x39\xe7\x35\x91\x28\x5e\x70\xb6\xdb".*,
+        "\xe6\x17\x34\x6a\xc9\xc2\x31\xbb\x36\x50\xae\x34\xcc\xca\x0c\x5b".*,
+        "\x27\xd9\x34\x37\xef\xb7\x21\xaa\x40\x18\x21\xdc\xec\x5a\xdf\x89".*,
+        "\x89\x23\x7d\x9d\xed\x9c\x5e\x78\xd8\xb1\xc9\xb1\x66\xcc\x73\x42".*,
+        "\x4a\x6d\x80\x91\xbf\x5e\x7d\x65\x11\x89\xfa\x94\xa2\x50\xb1\x4c".*,
+        "\x0e\x33\xf9\x60\x55\xe7\xae\x89\x3f\xfc\x0e\x3d\xcf\x49\x29\x02".*,
+        "\xe6\x1c\x43\x2b\x72\x0b\x19\xd1\x8e\xc8\xd8\x4b\xdc\x63\x15\x1b".*,
+        "\xf7\xe5\xae\xf5\x49\xf7\x82\xcf\x37\x90\x55\xa6\x08\x26\x9b\x16".*,
+        "\x43\x8d\x03\x0f\xd0\xb7\xa5\x4f\xa8\x37\xf2\xad\x20\x1a\x64\x03".*,
+        "\xa5\x90\xd3\xee\x4f\xbf\x04\xe3\x24\x7e\x0d\x27\xf2\x86\x42\x3f".*,
+        "\x5f\xe2\xc1\xa1\x72\xfe\x93\xc4\xb1\x5c\xd3\x7c\xae\xf9\xf5\x38".*,
+        "\x2c\x97\x32\x5c\xbd\x06\xb3\x6e\xb2\x13\x3d\xd0\x8b\x3a\x01\x7c".*,
+        "\x92\xc8\x14\x22\x7a\x6b\xca\x94\x9f\xf0\x65\x9f\x00\x2a\xd3\x9e".*,
+        "\xdc\xe8\x50\x11\x0b\xd8\x32\x8c\xfb\xd5\x08\x41\xd6\x91\x1d\x87".*,
+        "\x67\xf1\x49\x84\xc7\xda\x79\x12\x48\xe3\x2b\xb5\x92\x25\x83\xda".*,
+        "\x19\x38\xf2\xcf\x72\xd5\x4e\xe9\x7e\x94\x16\x6f\xa9\x1d\x2a\x36".*,
+        "\x74\x48\x1e\x96\x46\xed\x49\xfe\x0f\x62\x24\x30\x16\x04\x69\x8e".*,
+        "\x57\xfc\xa5\xde\x98\xa9\xd6\xd8\x00\x64\x38\xd0\x58\x3d\x8a\x1d".*,
+        "\x9f\xec\xde\x1c\xef\xdc\x1c\xbe\xd4\x76\x36\x74\xd9\x57\x53\x59".*,
+        "\xe3\x04\x0c\x00\xeb\x28\xf1\x53\x66\xca\x73\xcb\xd8\x72\xe7\x40".*,
+        "\x76\x97\x00\x9a\x6a\x83\x1d\xfe\xcc\xa9\x1c\x59\x93\x67\x0f\x7a".*,
+        "\x58\x53\x54\x23\x21\xf5\x67\xa0\x05\xd5\x47\xa4\xf0\x47\x59\xbd".*,
+        "\x51\x50\xd1\x77\x2f\x50\x83\x4a\x50\x3e\x06\x9a\x97\x3f\xbd\x7c".*,
     };
 
     const siphash = SipHash128(2, 4);
lib/std/io/test.zig
@@ -595,8 +595,8 @@ test "Deserializer bad data" {
 test "c out stream" {
     if (!builtin.link_libc) return error.SkipZigTest;
 
-    const filename = c"tmp_io_test_file.txt";
-    const out_file = std.c.fopen(filename, c"w") orelse return error.UnableToOpenTestFile;
+    const filename = "tmp_io_test_file.txt";
+    const out_file = std.c.fopen(filename, "w") orelse return error.UnableToOpenTestFile;
     defer {
         _ = std.c.fclose(out_file);
         fs.deleteFileC(filename) catch {};
lib/std/meta/trait.zig
@@ -319,7 +319,6 @@ test "std.meta.trait.isNumber" {
     testing.expect(!isNumber(NotANumber));
 }
 
-///
 pub fn isConstPtr(comptime T: type) bool {
     if (!comptime is(builtin.TypeId.Pointer)(T)) return false;
     const info = @typeInfo(T);
@@ -335,7 +334,6 @@ test "std.meta.trait.isConstPtr" {
     testing.expect(!isConstPtr(@typeOf(6)));
 }
 
-///
 pub fn isContainer(comptime T: type) bool {
     const info = @typeInfo(T);
     return switch (info) {
lib/std/os/linux/test.zig
@@ -56,7 +56,7 @@ test "statx" {
     }
 
     var statx_buf: linux.Statx = undefined;
-    switch (linux.getErrno(linux.statx(file.handle, c"", linux.AT_EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {
+    switch (linux.getErrno(linux.statx(file.handle, "", linux.AT_EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {
         0 => {},
         // The statx syscall was only introduced in linux 4.11
         linux.ENOSYS => return error.SkipZigTest,
@@ -64,7 +64,7 @@ test "statx" {
     }
 
     var stat_buf: linux.Stat = undefined;
-    switch (linux.getErrno(linux.fstatat(file.handle, c"", &stat_buf, linux.AT_EMPTY_PATH))) {
+    switch (linux.getErrno(linux.fstatat(file.handle, "", &stat_buf, linux.AT_EMPTY_PATH))) {
         0 => {},
         else => unreachable,
     }
lib/std/os/linux.zig
@@ -1053,7 +1053,7 @@ pub fn dl_iterate_phdr(comptime T: type, callback: extern fn (info: *dl_phdr_inf
     if (it.end()) {
         var info = dl_phdr_info{
             .dlpi_addr = elf_base,
-            .dlpi_name = c"/proc/self/exe",
+            .dlpi_name = "/proc/self/exe",
             .dlpi_phdr = @intToPtr([*]elf.Phdr, elf_base + __ehdr_start.e_phoff),
             .dlpi_phnum = __ehdr_start.e_phnum,
         };
lib/std/special/c.zig
@@ -66,14 +66,14 @@ extern fn strncmp(_l: [*]const u8, _r: [*]const u8, _n: usize) c_int {
 }
 
 extern fn strerror(errnum: c_int) [*]const u8 {
-    return c"TODO strerror implementation";
+    return "TODO strerror implementation";
 }
 
 test "strncmp" {
-    std.testing.expect(strncmp(c"a", c"b", 1) == -1);
-    std.testing.expect(strncmp(c"a", c"c", 1) == -2);
-    std.testing.expect(strncmp(c"b", c"a", 1) == 1);
-    std.testing.expect(strncmp(c"\xff", c"\x02", 1) == 253);
+    std.testing.expect(strncmp("a", "b", 1) == -1);
+    std.testing.expect(strncmp("a", "c", 1) == -2);
+    std.testing.expect(strncmp("b", "a", 1) == 1);
+    std.testing.expect(strncmp("\xff", "\x02", 1) == 253);
 }
 
 // Avoid dragging in the runtime safety mechanisms into this .o file,
lib/std/valgrind/memcheck.zig
@@ -3,7 +3,7 @@ const testing = std.testing;
 const valgrind = std.valgrind;
 
 pub const MemCheckClientRequest = extern enum {
-    MakeMemNoAccess = valgrind.ToolBase("MC"),
+    MakeMemNoAccess = valgrind.ToolBase("MC".*),
     MakeMemUndefined,
     MakeMemDefined,
     Discard,
lib/std/child_process.zig
@@ -328,7 +328,7 @@ pub const ChildProcess = struct {
 
         const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
         const dev_null_fd = if (any_ignore)
-            os.openC(c"/dev/null", os.O_RDWR, 0) catch |err| switch (err) {
+            os.openC("/dev/null", os.O_RDWR, 0) catch |err| switch (err) {
                 error.PathAlreadyExists => unreachable,
                 error.NoSpaceLeft => unreachable,
                 error.FileTooBig => unreachable,
lib/std/cstr.zig
@@ -27,8 +27,8 @@ test "cstr fns" {
 }
 
 fn testCStrFnsImpl() void {
-    testing.expect(cmp(c"aoeu", c"aoez") == -1);
-    testing.expect(mem.len(u8, c"123456789") == 9);
+    testing.expect(cmp("aoeu", "aoez") == -1);
+    testing.expect(mem.len(u8, "123456789") == 9);
 }
 
 /// Returns a mutable slice with 1 more byte of length which is a null byte.
lib/std/fmt.zig
@@ -1,8 +1,6 @@
 const std = @import("std.zig");
 const math = std.math;
-const debug = std.debug;
-const assert = debug.assert;
-const testing = std.testing;
+const assert = std.debug.assert;
 const mem = std.mem;
 const builtin = @import("builtin");
 const errol = @import("fmt/errol.zig");
@@ -36,7 +34,7 @@ fn nextArg(comptime used_pos_args: *u32, comptime maybe_pos_arg: ?comptime_int,
 
 fn peekIsAlign(comptime fmt: []const u8) bool {
     // Should only be called during a state transition to the format segment.
-    std.debug.assert(fmt[0] == ':');
+    comptime assert(fmt[0] == ':');
 
     inline for (([_]u8{ 1, 2 })[0..]) |i| {
         if (fmt.len > i and (fmt[i] == '<' or fmt[i] == '^' or fmt[i] == '>')) {
@@ -1009,13 +1007,13 @@ pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) !T {
 }
 
 test "parseInt" {
-    testing.expect((parseInt(i32, "-10", 10) catch unreachable) == -10);
-    testing.expect((parseInt(i32, "+10", 10) catch unreachable) == 10);
-    testing.expect(if (parseInt(i32, " 10", 10)) |_| false else |err| err == error.InvalidCharacter);
-    testing.expect(if (parseInt(i32, "10 ", 10)) |_| false else |err| err == error.InvalidCharacter);
-    testing.expect(if (parseInt(u32, "-10", 10)) |_| false else |err| err == error.InvalidCharacter);
-    testing.expect((parseInt(u8, "255", 10) catch unreachable) == 255);
-    testing.expect(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);
+    std.testing.expect((parseInt(i32, "-10", 10) catch unreachable) == -10);
+    std.testing.expect((parseInt(i32, "+10", 10) catch unreachable) == 10);
+    std.testing.expect(if (parseInt(i32, " 10", 10)) |_| false else |err| err == error.InvalidCharacter);
+    std.testing.expect(if (parseInt(i32, "10 ", 10)) |_| false else |err| err == error.InvalidCharacter);
+    std.testing.expect(if (parseInt(u32, "-10", 10)) |_| false else |err| err == error.InvalidCharacter);
+    std.testing.expect((parseInt(u8, "255", 10) catch unreachable) == 255);
+    std.testing.expect(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);
 }
 
 const ParseUnsignedError = error{
@@ -1040,30 +1038,30 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseUnsigned
 }
 
 test "parseUnsigned" {
-    testing.expect((try parseUnsigned(u16, "050124", 10)) == 50124);
-    testing.expect((try parseUnsigned(u16, "65535", 10)) == 65535);
-    testing.expectError(error.Overflow, parseUnsigned(u16, "65536", 10));
+    std.testing.expect((try parseUnsigned(u16, "050124", 10)) == 50124);
+    std.testing.expect((try parseUnsigned(u16, "65535", 10)) == 65535);
+    std.testing.expectError(error.Overflow, parseUnsigned(u16, "65536", 10));
 
-    testing.expect((try parseUnsigned(u64, "0ffffffffffffffff", 16)) == 0xffffffffffffffff);
-    testing.expectError(error.Overflow, parseUnsigned(u64, "10000000000000000", 16));
+    std.testing.expect((try parseUnsigned(u64, "0ffffffffffffffff", 16)) == 0xffffffffffffffff);
+    std.testing.expectError(error.Overflow, parseUnsigned(u64, "10000000000000000", 16));
 
-    testing.expect((try parseUnsigned(u32, "DeadBeef", 16)) == 0xDEADBEEF);
+    std.testing.expect((try parseUnsigned(u32, "DeadBeef", 16)) == 0xDEADBEEF);
 
-    testing.expect((try parseUnsigned(u7, "1", 10)) == 1);
-    testing.expect((try parseUnsigned(u7, "1000", 2)) == 8);
+    std.testing.expect((try parseUnsigned(u7, "1", 10)) == 1);
+    std.testing.expect((try parseUnsigned(u7, "1000", 2)) == 8);
 
-    testing.expectError(error.InvalidCharacter, parseUnsigned(u32, "f", 10));
-    testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "109", 8));
+    std.testing.expectError(error.InvalidCharacter, parseUnsigned(u32, "f", 10));
+    std.testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "109", 8));
 
-    testing.expect((try parseUnsigned(u32, "NUMBER", 36)) == 1442151747);
+    std.testing.expect((try parseUnsigned(u32, "NUMBER", 36)) == 1442151747);
 
     // these numbers should fit even though the radix itself doesn't fit in the destination type
-    testing.expect((try parseUnsigned(u1, "0", 10)) == 0);
-    testing.expect((try parseUnsigned(u1, "1", 10)) == 1);
-    testing.expectError(error.Overflow, parseUnsigned(u1, "2", 10));
-    testing.expect((try parseUnsigned(u1, "001", 16)) == 1);
-    testing.expect((try parseUnsigned(u2, "3", 16)) == 3);
-    testing.expectError(error.Overflow, parseUnsigned(u2, "4", 16));
+    std.testing.expect((try parseUnsigned(u1, "0", 10)) == 0);
+    std.testing.expect((try parseUnsigned(u1, "1", 10)) == 1);
+    std.testing.expectError(error.Overflow, parseUnsigned(u1, "2", 10));
+    std.testing.expect((try parseUnsigned(u1, "001", 16)) == 1);
+    std.testing.expect((try parseUnsigned(u2, "3", 16)) == 3);
+    std.testing.expectError(error.Overflow, parseUnsigned(u2, "4", 16));
 }
 
 pub const parseFloat = @import("fmt/parse_float.zig").parseFloat;
@@ -1134,19 +1132,19 @@ fn countSize(size: *usize, bytes: []const u8) (error{}!void) {
 test "bufPrintInt" {
     var buffer: [100]u8 = undefined;
     const buf = buffer[0..];
-    testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 2, false, FormatOptions{}), "-101111000110000101001110"));
-    testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 10, false, FormatOptions{}), "-12345678"));
-    testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 16, false, FormatOptions{}), "-bc614e"));
-    testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 16, true, FormatOptions{}), "-BC614E"));
+    std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 2, false, FormatOptions{}), "-101111000110000101001110"));
+    std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 10, false, FormatOptions{}), "-12345678"));
+    std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 16, false, FormatOptions{}), "-bc614e"));
+    std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 16, true, FormatOptions{}), "-BC614E"));
 
-    testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 12345678), 10, true, FormatOptions{}), "12345678"));
+    std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 12345678), 10, true, FormatOptions{}), "12345678"));
 
-    testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 666), 10, false, FormatOptions{ .width = 6 }), "   666"));
-    testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 6 }), "  1234"));
-    testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 1 }), "1234"));
+    std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 666), 10, false, FormatOptions{ .width = 6 }), "   666"));
+    std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 6 }), "  1234"));
+    std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 1 }), "1234"));
 
-    testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, 42), 10, false, FormatOptions{ .width = 3 }), "+42"));
-    testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -42), 10, false, FormatOptions{ .width = 3 }), "-42"));
+    std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, 42), 10, false, FormatOptions{ .width = 3 }), "+42"));
+    std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -42), 10, false, FormatOptions{ .width = 3 }), "-42"));
 }
 
 fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, options: FormatOptions) []u8 {
@@ -1163,7 +1161,7 @@ test "parse u64 digit too big" {
 
 test "parse unsigned comptime" {
     comptime {
-        testing.expect((try parseUnsigned(usize, "2", 10)) == 2);
+        std.testing.expect((try parseUnsigned(usize, "2", 10)) == 2);
     }
 }
 
@@ -1218,23 +1216,23 @@ test "buffer" {
         var context = BufPrintContext{ .remaining = buf1[0..] };
         try formatType(1234, "", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);
         var res = buf1[0 .. buf1.len - context.remaining.len];
-        testing.expect(mem.eql(u8, res, "1234"));
+        std.testing.expect(mem.eql(u8, res, "1234"));
 
         context = BufPrintContext{ .remaining = buf1[0..] };
         try formatType('a', "c", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);
         res = buf1[0 .. buf1.len - context.remaining.len];
-        testing.expect(mem.eql(u8, res, "a"));
+        std.testing.expect(mem.eql(u8, res, "a"));
 
         context = BufPrintContext{ .remaining = buf1[0..] };
         try formatType(0b1100, "b", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);
         res = buf1[0 .. buf1.len - context.remaining.len];
-        testing.expect(mem.eql(u8, res, "1100"));
+        std.testing.expect(mem.eql(u8, res, "1100"));
     }
 }
 
 test "array" {
     {
-        const value: [3]u8 = "abc";
+        const value: [3]u8 = "abc".*;
         try testFmt("array: abc\n", "array: {}\n", value);
         try testFmt("array: abc\n", "array: {}\n", &value);
 
@@ -1278,8 +1276,8 @@ test "pointer" {
 }
 
 test "cstr" {
-    try testFmt("cstr: Test C\n", "cstr: {s}\n", c"Test C");
-    try testFmt("cstr: Test C    \n", "cstr: {s:10}\n", c"Test C");
+    try testFmt("cstr: Test C\n", "cstr: {s}\n", "Test C");
+    try testFmt("cstr: Test C    \n", "cstr: {s:10}\n", "Test C");
 }
 
 test "filesize" {
@@ -1479,10 +1477,10 @@ test "union" {
 
     var buf: [100]u8 = undefined;
     const uu_result = try bufPrint(buf[0..], "{}", uu_inst);
-    testing.expect(mem.eql(u8, uu_result[0..3], "UU@"));
+    std.testing.expect(mem.eql(u8, uu_result[0..3], "UU@"));
 
     const eu_result = try bufPrint(buf[0..], "{}", eu_inst);
-    testing.expect(mem.eql(u8, uu_result[0..3], "EU@"));
+    std.testing.expect(mem.eql(u8, uu_result[0..3], "EU@"));
 }
 
 test "enum" {
@@ -1569,11 +1567,11 @@ pub fn trim(buf: []const u8) []const u8 {
 }
 
 test "trim" {
-    testing.expect(mem.eql(u8, "abc", trim("\n  abc  \t")));
-    testing.expect(mem.eql(u8, "", trim("   ")));
-    testing.expect(mem.eql(u8, "", trim("")));
-    testing.expect(mem.eql(u8, "abc", trim(" abc")));
-    testing.expect(mem.eql(u8, "abc", trim("abc ")));
+    std.testing.expect(mem.eql(u8, "abc", trim("\n  abc  \t")));
+    std.testing.expect(mem.eql(u8, "", trim("   ")));
+    std.testing.expect(mem.eql(u8, "", trim("")));
+    std.testing.expect(mem.eql(u8, "abc", trim(" abc")));
+    std.testing.expect(mem.eql(u8, "abc", trim("abc ")));
 }
 
 pub fn isWhiteSpace(byte: u8) bool {
@@ -1607,7 +1605,7 @@ test "formatIntValue with comptime_int" {
 
     var buf = try std.Buffer.init(std.debug.global_allocator, "");
     try formatIntValue(value, "", FormatOptions{}, &buf, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append);
-    assert(mem.eql(u8, buf.toSlice(), "123456789123456789"));
+    std.testing.expect(mem.eql(u8, buf.toSlice(), "123456789123456789"));
 }
 
 test "formatType max_depth" {
@@ -1661,19 +1659,19 @@ test "formatType max_depth" {
 
     var buf0 = try std.Buffer.init(std.debug.global_allocator, "");
     try formatType(inst, "", FormatOptions{}, &buf0, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 0);
-    assert(mem.eql(u8, buf0.toSlice(), "S{ ... }"));
+    std.testing.expect(mem.eql(u8, buf0.toSlice(), "S{ ... }"));
 
     var buf1 = try std.Buffer.init(std.debug.global_allocator, "");
     try formatType(inst, "", FormatOptions{}, &buf1, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 1);
-    assert(mem.eql(u8, buf1.toSlice(), "S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }"));
+    std.testing.expect(mem.eql(u8, buf1.toSlice(), "S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }"));
 
     var buf2 = try std.Buffer.init(std.debug.global_allocator, "");
     try formatType(inst, "", FormatOptions{}, &buf2, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 2);
-    assert(mem.eql(u8, buf2.toSlice(), "S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }"));
+    std.testing.expect(mem.eql(u8, buf2.toSlice(), "S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }"));
 
     var buf3 = try std.Buffer.init(std.debug.global_allocator, "");
     try formatType(inst, "", FormatOptions{}, &buf3, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 3);
-    assert(mem.eql(u8, buf3.toSlice(), "S{ .a = S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ .ptr = TU{ ... } } }, .e = E.Two, .vec = (10.200,2.220) }"));
+    std.testing.expect(mem.eql(u8, buf3.toSlice(), "S{ .a = S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ .ptr = TU{ ... } } }, .e = E.Two, .vec = (10.200,2.220) }"));
 }
 
 test "positional" {
lib/std/fs.zig
@@ -1240,7 +1240,7 @@ pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError || SelfE
 
 pub fn openSelfExe() OpenSelfExeError!File {
     if (builtin.os == .linux) {
-        return File.openReadC(c"/proc/self/exe");
+        return File.openReadC("/proc/self/exe");
     }
     if (builtin.os == .windows) {
         const wide_slice = selfExePathW();
@@ -1280,7 +1280,7 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 {
         return mem.toSlice(u8, out_buffer);
     }
     switch (builtin.os) {
-        .linux => return os.readlinkC(c"/proc/self/exe", out_buffer),
+        .linux => return os.readlinkC("/proc/self/exe", out_buffer),
         .freebsd, .dragonfly => {
             var mib = [4]c_int{ os.CTL_KERN, os.KERN_PROC, os.KERN_PROC_PATHNAME, -1 };
             var out_len: usize = out_buffer.len;
@@ -1326,7 +1326,7 @@ pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]const
         // the file path looks something like `/a/b/c/exe (deleted)`
         // This path cannot be opened, but it's valid for determining the directory
         // the executable was in when it was run.
-        const full_exe_path = try os.readlinkC(c"/proc/self/exe", out_buffer);
+        const full_exe_path = try os.readlinkC("/proc/self/exe", out_buffer);
         // Assume that /proc/self/exe has an absolute path, and therefore dirname
         // will not return null.
         return path.dirname(full_exe_path).?;
lib/std/mem.zig
@@ -1408,7 +1408,9 @@ test "toBytes" {
 fn BytesAsValueReturnType(comptime T: type, comptime B: type) type {
     const size = @as(usize, @sizeOf(T));
 
-    if (comptime !trait.is(builtin.TypeId.Pointer)(B) or meta.Child(B) != [size]u8) {
+    if (comptime !trait.is(builtin.TypeId.Pointer)(B) or
+        (meta.Child(B) != [size]u8 and meta.Child(B) != [size]null u8))
+    {
         @compileError("expected *[N]u8 " ++ ", passed " ++ @typeName(B));
     }
 
@@ -1430,12 +1432,12 @@ test "bytesAsValue" {
         builtin.Endian.Little => "\xEF\xBE\xAD\xDE",
     };
 
-    testing.expect(deadbeef == bytesAsValue(u32, &deadbeef_bytes).*);
+    testing.expect(deadbeef == bytesAsValue(u32, deadbeef_bytes).*);
 
-    var codeface_bytes = switch (builtin.endian) {
+    var codeface_bytes: [4]u8 = switch (builtin.endian) {
         builtin.Endian.Big => "\xC0\xDE\xFA\xCE",
         builtin.Endian.Little => "\xCE\xFA\xDE\xC0",
-    };
+    }.*;
     var codeface = bytesAsValue(u32, &codeface_bytes);
     testing.expect(codeface.* == 0xC0DEFACE);
     codeface.* = 0;
@@ -1456,14 +1458,14 @@ test "bytesAsValue" {
         .d = 0xA1,
     };
     const inst_bytes = "\xBE\xEF\xDE\xA1";
-    const inst2 = bytesAsValue(S, &inst_bytes);
+    const inst2 = bytesAsValue(S, inst_bytes);
     testing.expect(meta.eql(inst, inst2.*));
 }
 
 ///Given a pointer to an array of bytes, returns a value of the specified type backed by a
 /// copy of those bytes.
 pub fn bytesToValue(comptime T: type, bytes: var) T {
-    return bytesAsValue(T, &bytes).*;
+    return bytesAsValue(T, bytes).*;
 }
 test "bytesToValue" {
     const deadbeef_bytes = switch (builtin.endian) {
@@ -1491,11 +1493,11 @@ pub fn subArrayPtr(ptr: var, comptime start: usize, comptime length: usize) SubA
 }
 
 test "subArrayPtr" {
-    const a1 = "abcdef";
+    const a1: [6]u8 = "abcdef".*;
     const sub1 = subArrayPtr(&a1, 2, 3);
     testing.expect(eql(u8, sub1.*, "cde"));
 
-    var a2 = "abcdef";
+    var a2: [6]u8 = "abcdef".*;
     var sub2 = subArrayPtr(&a2, 2, 3);
 
     testing.expect(eql(u8, sub2, "cde"));
lib/std/meta.zig
@@ -469,19 +469,19 @@ test "std.meta.eql" {
     const s_1 = S{
         .a = 134,
         .b = 123.3,
-        .c = "12345",
+        .c = "12345".*,
     };
 
     const s_2 = S{
         .a = 1,
         .b = 123.3,
-        .c = "54321",
+        .c = "54321".*,
     };
 
     const s_3 = S{
         .a = 134,
         .b = 123.3,
-        .c = "12345",
+        .c = "12345".*,
     };
 
     const u_1 = U{ .f = 24 };
@@ -494,9 +494,9 @@ test "std.meta.eql" {
     testing.expect(eql(u_1, u_3));
     testing.expect(!eql(u_1, u_2));
 
-    var a1 = "abcdef";
-    var a2 = "abcdef";
-    var a3 = "ghijkl";
+    var a1 = "abcdef".*;
+    var a2 = "abcdef".*;
+    var a3 = "ghijkl".*;
 
     testing.expect(eql(a1, a2));
     testing.expect(!eql(a1, a3));
@@ -558,4 +558,3 @@ pub fn refAllDecls(comptime T: type) void {
     if (!builtin.is_test) return;
     _ = declarations(T);
 }
-
lib/std/net.zig
@@ -666,35 +666,35 @@ const Policy = struct {
 
 const defined_policies = [_]Policy{
     Policy{
-        .addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
+        .addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01".*,
         .len = 15,
         .mask = 0xff,
         .prec = 50,
         .label = 0,
     },
     Policy{
-        .addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00",
+        .addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00".*,
         .len = 11,
         .mask = 0xff,
         .prec = 35,
         .label = 4,
     },
     Policy{
-        .addr = "\x20\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        .addr = "\x20\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*,
         .len = 1,
         .mask = 0xff,
         .prec = 30,
         .label = 2,
     },
     Policy{
-        .addr = "\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        .addr = "\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*,
         .len = 3,
         .mask = 0xff,
         .prec = 5,
         .label = 5,
     },
     Policy{
-        .addr = "\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        .addr = "\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*,
         .len = 0,
         .mask = 0xfe,
         .prec = 3,
@@ -708,7 +708,7 @@ const defined_policies = [_]Policy{
     // { "\x3f\xfe", 1, 0xff, 1, 12 },
     // Last rule must match all addresses to stop loop.
     Policy{
-        .addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        .addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*,
         .len = 0,
         .mask = 0,
         .prec = 40,
@@ -812,7 +812,7 @@ fn linuxLookupNameFromHosts(
     family: os.sa_family_t,
     port: u16,
 ) !void {
-    const file = fs.File.openReadC(c"/etc/hosts") catch |err| switch (err) {
+    const file = fs.File.openReadC("/etc/hosts") catch |err| switch (err) {
         error.FileNotFound,
         error.NotDir,
         error.AccessDenied,
@@ -1006,7 +1006,7 @@ fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void {
     };
     errdefer rc.deinit();
 
-    const file = fs.File.openReadC(c"/etc/resolv.conf") catch |err| switch (err) {
+    const file = fs.File.openReadC("/etc/resolv.conf") catch |err| switch (err) {
         error.FileNotFound,
         error.NotDir,
         error.AccessDenied,
lib/std/os.zig
@@ -157,7 +157,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
 }
 
 fn getRandomBytesDevURandom(buf: []u8) !void {
-    const fd = try openC(c"/dev/urandom", O_RDONLY | O_CLOEXEC, 0);
+    const fd = try openC("/dev/urandom", O_RDONLY | O_CLOEXEC, 0);
     defer close(fd);
 
     const st = try fstat(fd);
@@ -2674,7 +2674,7 @@ pub fn dl_iterate_phdr(
     if (it.end()) {
         var info = dl_phdr_info{
             .dlpi_addr = elf_base,
-            .dlpi_name = c"/proc/self/exe",
+            .dlpi_name = "/proc/self/exe",
             .dlpi_phdr = phdrs.ptr,
             .dlpi_phnum = ehdr.e_phnum,
         };
lib/std/process.zig
@@ -473,14 +473,14 @@ pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void {
 }
 
 test "windows arg parsing" {
-    testWindowsCmdLine(c"a   b\tc d", [_][]const u8{ "a", "b", "c", "d" });
-    testWindowsCmdLine(c"\"abc\" d e", [_][]const u8{ "abc", "d", "e" });
-    testWindowsCmdLine(c"a\\\\\\b d\"e f\"g h", [_][]const u8{ "a\\\\\\b", "de fg", "h" });
-    testWindowsCmdLine(c"a\\\\\\\"b c d", [_][]const u8{ "a\\\"b", "c", "d" });
-    testWindowsCmdLine(c"a\\\\\\\\\"b c\" d e", [_][]const u8{ "a\\\\b c", "d", "e" });
-    testWindowsCmdLine(c"a   b\tc \"d f", [_][]const u8{ "a", "b", "c", "\"d", "f" });
-
-    testWindowsCmdLine(c"\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", [_][]const u8{
+    testWindowsCmdLine("a   b\tc d", [_][]const u8{ "a", "b", "c", "d" });
+    testWindowsCmdLine("\"abc\" d e", [_][]const u8{ "abc", "d", "e" });
+    testWindowsCmdLine("a\\\\\\b d\"e f\"g h", [_][]const u8{ "a\\\\\\b", "de fg", "h" });
+    testWindowsCmdLine("a\\\\\\\"b c d", [_][]const u8{ "a\\\"b", "c", "d" });
+    testWindowsCmdLine("a\\\\\\\\\"b c\" d e", [_][]const u8{ "a\\\\b c", "d", "e" });
+    testWindowsCmdLine("a   b\tc \"d f", [_][]const u8{ "a", "b", "c", "\"d", "f" });
+
+    testWindowsCmdLine("\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", [_][]const u8{
         ".\\..\\zig-cache\\build",
         "bin\\zig.exe",
         ".\\..",
lib/std/thread.zig
@@ -353,7 +353,7 @@ pub const Thread = struct {
         }
         var count: c_int = undefined;
         var count_len: usize = @sizeOf(c_int);
-        const name = if (comptime std.Target.current.isDarwin()) c"hw.logicalcpu" else c"hw.ncpu";
+        const name = if (comptime std.Target.current.isDarwin()) "hw.logicalcpu" else "hw.ncpu";
         os.sysctlbynameC(name, &count, &count_len, null, 0) catch |err| switch (err) {
             error.NameTooLong => unreachable,
             else => |e| return e,
src/all_types.hpp
@@ -102,6 +102,10 @@ struct IrExecutable {
     bool is_inline;
     bool is_generic_instantiation;
     bool need_err_code_spill;
+
+    // This is a function for use in the debugger to print
+    // the source location.
+    void src();
 };
 
 enum OutType {
@@ -237,9 +241,6 @@ struct ConstPtrValue {
         struct {
             ConstExprValue *array_val;
             size_t elem_index;
-            // This helps us preserve the null byte when performing compile-time
-            // concatenation on C strings.
-            bool is_cstr;
         } base_array;
         struct {
             ConstExprValue *struct_val;
@@ -1001,7 +1002,6 @@ struct AstNodeStructField {
 
 struct AstNodeStringLiteral {
     Buf *buf;
-    bool c;
 };
 
 struct AstNodeCharLiteral {
@@ -1956,6 +1956,7 @@ struct CodeGen {
     HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;
     HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> string_literals_table;
     HashMap<const ZigType *, ConstExprValue *, type_ptr_hash, type_ptr_eql> type_info_cache;
+    HashMap<const ZigType *, ConstExprValue *, type_ptr_hash, type_ptr_eql> one_possible_values;
 
     ZigList<Tld *> resolve_queue;
     size_t resolve_queue_index;
src/analyze.cpp
@@ -767,10 +767,18 @@ ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size, bo
 
     ZigType *entry = new_type_table_entry(ZigTypeIdArray);
 
+    const char *null_str = is_null_terminated ? "null " : "";
+
     buf_resize(&entry->name, 0);
-    buf_appendf(&entry->name, "[%" ZIG_PRI_u64 "]%s", array_size, buf_ptr(&child_type->name));
+    buf_appendf(&entry->name, "[%" ZIG_PRI_u64 "]%s%s", array_size, null_str, buf_ptr(&child_type->name));
+
+    size_t full_array_size;
+    if (array_size == 0) {
+        full_array_size = 0;
+    } else {
+        full_array_size = array_size + (is_null_terminated ? 1 : 0);
+    }
 
-    size_t full_array_size = array_size + (is_null_terminated ? 1 : 0);
     entry->size_in_bits = child_type->size_in_bits * full_array_size;
     entry->abi_align = child_type->abi_align;
     entry->abi_size = child_type->abi_size * full_array_size;
@@ -5046,7 +5054,6 @@ static uint32_t hash_const_val_ptr(ConstExprValue *const_val) {
             hash_val += (uint32_t)1764906839;
             hash_val += hash_ptr(const_val->data.x_ptr.data.base_array.array_val);
             hash_val += hash_size(const_val->data.x_ptr.data.base_array.elem_index);
-            hash_val += const_val->data.x_ptr.data.base_array.is_cstr ? 1297263887 : 200363492;
             return hash_val;
         case ConstPtrSpecialBaseStruct:
             hash_val += (uint32_t)3518317043;
@@ -5550,6 +5557,18 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
     zig_unreachable();
 }
 
+ConstExprValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
+    auto entry = g->one_possible_values.maybe_get(type_entry);
+    if (entry != nullptr) {
+        return entry->value;
+    }
+    ConstExprValue *result = create_const_vals(1);
+    result->type = type_entry;
+    result->special = ConstValSpecialStatic;
+    g->one_possible_values.put(type_entry, result);
+    return result;
+}
+
 ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) {
     Error err;
     switch (ty->id) {
@@ -5617,52 +5636,26 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
         return;
     }
 
-    const_val->special = ConstValSpecialStatic;
-    const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str), false);
-    const_val->data.x_array.special = ConstArraySpecialBuf;
-    const_val->data.x_array.data.s_buf = str;
-
-    g->string_literals_table.put(str, const_val);
-}
-
-ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) {
-    ConstExprValue *const_val = create_const_vals(1);
-    init_const_str_lit(g, const_val, str);
-    return const_val;
-}
-
-void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
     // first we build the underlying array
-    size_t len_with_null = buf_len(str) + 1;
     ConstExprValue *array_val = create_const_vals(1);
     array_val->special = ConstValSpecialStatic;
-    array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null, false);
-    // TODO buf optimization
-    array_val->data.x_array.data.s_none.elements = create_const_vals(len_with_null);
-    for (size_t i = 0; i < buf_len(str); i += 1) {
-        ConstExprValue *this_char = &array_val->data.x_array.data.s_none.elements[i];
-        this_char->special = ConstValSpecialStatic;
-        this_char->type = g->builtin_types.entry_u8;
-        bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]);
-    }
-    ConstExprValue *null_char = &array_val->data.x_array.data.s_none.elements[len_with_null - 1];
-    null_char->special = ConstValSpecialStatic;
-    null_char->type = g->builtin_types.entry_u8;
-    bigint_init_unsigned(&null_char->data.x_bigint, 0);
+    array_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str), true);
+    array_val->data.x_array.special = ConstArraySpecialBuf;
+    array_val->data.x_array.data.s_buf = str;
 
     // then make the pointer point to it
     const_val->special = ConstValSpecialStatic;
-    // TODO make this `[*]null u8` instead of `[*]u8`
-    const_val->type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
-            PtrLenUnknown, 0, 0, 0, false);
-    const_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
-    const_val->data.x_ptr.data.base_array.array_val = array_val;
-    const_val->data.x_ptr.data.base_array.elem_index = 0;
-    const_val->data.x_ptr.data.base_array.is_cstr = true;
+    const_val->type = get_pointer_to_type_extra2(g, array_val->type, true, false,
+            PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr);
+    const_val->data.x_ptr.special = ConstPtrSpecialRef;
+    const_val->data.x_ptr.data.ref.pointee = array_val;
+
+    g->string_literals_table.put(str, const_val);
 }
-ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *str) {
+
+ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) {
     ConstExprValue *const_val = create_const_vals(1);
-    init_const_c_str_lit(g, const_val, str);
+    init_const_str_lit(g, const_val, str);
     return const_val;
 }
 
@@ -5712,6 +5705,18 @@ ConstExprValue *create_const_signed(ZigType *type, int64_t x) {
     return const_val;
 }
 
+void init_const_null(ConstExprValue *const_val, ZigType *type) {
+    const_val->special = ConstValSpecialStatic;
+    const_val->type = type;
+    const_val->data.x_optional = nullptr;
+}
+
+ConstExprValue *create_const_null(ZigType *type) {
+    ConstExprValue *const_val = create_const_vals(1);
+    init_const_null(const_val, type);
+    return const_val;
+}
+
 void init_const_float(ConstExprValue *const_val, ZigType *type, double value) {
     const_val->special = ConstValSpecialStatic;
     const_val->type = type;
@@ -6446,8 +6451,6 @@ bool ir_get_var_is_comptime(ZigVar *var) {
 bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) {
     if (a->data.x_ptr.special != b->data.x_ptr.special)
         return false;
-    if (a->data.x_ptr.mut != b->data.x_ptr.mut)
-        return false;
     switch (a->data.x_ptr.special) {
         case ConstPtrSpecialInvalid:
             zig_unreachable();
@@ -6464,8 +6467,6 @@ bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) {
             }
             if (a->data.x_ptr.data.base_array.elem_index != b->data.x_ptr.data.base_array.elem_index)
                 return false;
-            if (a->data.x_ptr.data.base_array.is_cstr != b->data.x_ptr.data.base_array.is_cstr)
-                return false;
             return true;
         case ConstPtrSpecialBaseStruct:
             if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val &&
@@ -6544,6 +6545,16 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
     assert(a->type->id == b->type->id);
     assert(a->special == ConstValSpecialStatic);
     assert(b->special == ConstValSpecialStatic);
+    if (a->type == b->type) {
+        switch (type_has_one_possible_value(g, a->type)) {
+            case OnePossibleValueInvalid:
+                zig_unreachable();
+            case OnePossibleValueNo:
+                break;
+            case OnePossibleValueYes:
+                return true;
+        }
+    }
     switch (a->type->id) {
         case ZigTypeIdOpaque:
             zig_unreachable();
@@ -6709,15 +6720,10 @@ static void render_const_val_ptr(CodeGen *g, Buf *buf, ConstExprValue *const_val
             render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr));
             return;
         case ConstPtrSpecialBaseArray:
-            if (const_val->data.x_ptr.data.base_array.is_cstr) {
-                buf_appendf(buf, "*(c str lit)");
-                return;
-            } else {
-                buf_appendf(buf, "*");
-                // TODO we need a source node for const_ptr_pointee because it can generate compile errors
-                render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr));
-                return;
-            }
+            buf_appendf(buf, "*");
+            // TODO we need a source node for const_ptr_pointee because it can generate compile errors
+            render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr));
+            return;
         case ConstPtrSpecialHardCodedAddr:
             buf_appendf(buf, "(%s)(%" ZIG_PRI_x64 ")", buf_ptr(&type_entry->name),
                     const_val->data.x_ptr.data.hard_coded_addr.addr);
@@ -8653,14 +8659,16 @@ static void resolve_llvm_types_array(CodeGen *g, ZigType *type) {
 
     ZigType *elem_type = type->data.array.child_type;
 
+    uint64_t extra_len_from_null = type->data.array.is_null_terminated ? 1 : 0;
+    uint64_t full_len = type->data.array.len + extra_len_from_null;
     // TODO https://github.com/ziglang/zig/issues/1424
-    type->llvm_type = LLVMArrayType(get_llvm_type(g, elem_type), (unsigned)type->data.array.len);
+    type->llvm_type = LLVMArrayType(get_llvm_type(g, elem_type), (unsigned)full_len);
 
     uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, type->llvm_type);
     uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, type->llvm_type);
 
     type->llvm_di_type = ZigLLVMCreateDebugArrayType(g->dbuilder, debug_size_in_bits,
-            debug_align_in_bits, get_llvm_di_type(g, elem_type), (int)type->data.array.len);
+            debug_align_in_bits, get_llvm_di_type(g, elem_type), (int)full_len);
 }
 
 static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) {
@@ -9150,3 +9158,24 @@ Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str,
     *out_import = add_source_file(g, target_package, resolved_path, import_code, source_kind);
     return ErrorNone;
 }
+
+
+void IrExecutable::src() {
+    IrExecutable *it;
+    for (it = this; it != nullptr && it->source_node != nullptr; it = it->parent_exec) {
+        it->source_node->src();
+    }
+}
+
+ConstExprValue *get_null_value(ZigType *ty) {
+    if (ty->id == ZigTypeIdInt || ty->id == ZigTypeIdComptimeInt) {
+        return create_const_unsigned_negative(ty, 0, false);
+    } else if (ty->id == ZigTypeIdFloat || ty->id == ZigTypeIdComptimeFloat) {
+        return create_const_float(ty, NAN);
+    } else if (ty->id == ZigTypeIdOptional) {
+        return create_const_null(ty);
+    } else {
+        zig_unreachable();
+    }
+}
+
src/analyze.hpp
@@ -126,9 +126,6 @@ ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent);
 void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str);
 ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str);
 
-void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *c_str);
-ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *c_str);
-
 void init_const_bigint(ConstExprValue *const_val, ZigType *type, const BigInt *bigint);
 ConstExprValue *create_const_bigint(ZigType *type, const BigInt *bigint);
 
@@ -176,6 +173,9 @@ ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t
 void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end);
 ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);
 
+void init_const_null(ConstExprValue *const_val, ZigType *type);
+ConstExprValue *create_const_null(ZigType *type);
+
 ConstExprValue *create_const_vals(size_t count);
 ConstExprValue **alloc_const_vals_ptrs(size_t count);
 ConstExprValue **realloc_const_vals_ptrs(ConstExprValue **ptr, size_t old_count, size_t new_count);
@@ -275,5 +275,6 @@ IrInstruction *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node,
         ZigType *var_type, const char *name_hint);
 Error analyze_import(CodeGen *codegen, ZigType *source_import, Buf *import_target_str,
         ZigType **out_import, Buf **out_import_target_path, Buf *out_full_path);
-
+ConstExprValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry);
+ConstExprValue *get_null_value(ZigType *ty);
 #endif
src/ast_render.cpp
@@ -619,9 +619,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
             break;
         case NodeTypeStringLiteral:
             {
-                if (node->data.string_literal.c) {
-                    fprintf(ar->f, "c");
-                }
                 Buf tmp_buf = BUF_INIT;
                 string_literal_escape(node->data.string_literal.buf, &tmp_buf);
                 fprintf(ar->f, "\"%s\"", buf_ptr(&tmp_buf));
src/codegen.cpp
@@ -949,7 +949,7 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) {
     if (!val->global_refs->llvm_global) {
 
         Buf *buf_msg = panic_msg_buf(msg_id);
-        ConstExprValue *array_val = create_const_str_lit(g, buf_msg);
+        ConstExprValue *array_val = create_const_str_lit(g, buf_msg)->data.x_ptr.data.ref.pointee;
         init_const_slice(g, val, array_val, 0, buf_len(buf_msg), true);
 
         render_const_val(g, val, "");
@@ -2784,14 +2784,6 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
     IrInstruction *op1 = bin_op_instruction->op1;
     IrInstruction *op2 = bin_op_instruction->op2;
 
-    assert(op1->value.type == op2->value.type || op_id == IrBinOpBitShiftLeftLossy ||
-        op_id == IrBinOpBitShiftLeftExact || op_id == IrBinOpBitShiftRightLossy ||
-        op_id == IrBinOpBitShiftRightExact ||
-        (op1->value.type->id == ZigTypeIdErrorSet && op2->value.type->id == ZigTypeIdErrorSet) ||
-        (op1->value.type->id == ZigTypeIdPointer &&
-            (op_id == IrBinOpAdd || op_id == IrBinOpSub) &&
-            op1->value.type->data.pointer.ptr_len != PtrLenSingle)
-    );
     ZigType *operand_type = op1->value.type;
     ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type;
 
@@ -2848,7 +2840,6 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
                 AddSubMulMul;
 
             if (scalar_type->id == ZigTypeIdPointer) {
-                assert(scalar_type->data.pointer.ptr_len != PtrLenSingle);
                 LLVMValueRef subscript_value;
                 if (operand_type->id == ZigTypeIdVector)
                     zig_panic("TODO: Implement vector operations on pointers.");
@@ -3077,7 +3068,14 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
         case CastOpNumLitToConcrete:
             zig_unreachable();
         case CastOpNoop:
-            return expr_val;
+            if (actual_type->id == ZigTypeIdPointer && wanted_type->id == ZigTypeIdPointer &&
+                actual_type->data.pointer.child_type->id == ZigTypeIdArray &&
+                wanted_type->data.pointer.child_type->id == ZigTypeIdArray)
+            {
+                return LLVMBuildBitCast(g->builder, expr_val, get_llvm_type(g, wanted_type), "");
+            } else {
+                return expr_val;
+            }
         case CastOpIntToFloat:
             assert(actual_type->id == ZigTypeIdInt);
             if (actual_type->data.integral.is_signed) {
@@ -3709,8 +3707,9 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
             array_type = array_type->data.pointer.child_type;
         }
         if (safety_check_on) {
-            LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
-                    array_type->data.array.len, false);
+            uint64_t extra_len_from_null = array_type->data.array.is_null_terminated ? 1 : 0;
+            uint64_t full_len = array_type->data.array.len + extra_len_from_null;
+            LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, full_len, false);
             add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, end);
         }
         if (array_ptr_type->data.pointer.host_int_bytes != 0) {
@@ -6637,11 +6636,20 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con
                 ConstExprValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val;
                 assert(array_const_val->type->id == ZigTypeIdArray);
                 if (!type_has_bits(array_const_val->type)) {
-                    // make this a null pointer
-                    ZigType *usize = g->builtin_types.entry_usize;
-                    const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type),
-                            get_llvm_type(g, const_val->type));
-                    return const_val->global_refs->llvm_value;
+                    if (array_const_val->type->data.array.is_null_terminated) {
+                        ConstExprValue *pointee = get_null_value(array_const_val->type->data.array.child_type);
+                        render_const_val(g, pointee, "");
+                        render_const_val_global(g, pointee, "");
+                        const_val->global_refs->llvm_value = LLVMConstBitCast(pointee->global_refs->llvm_global,
+                                get_llvm_type(g, const_val->type));
+                        return const_val->global_refs->llvm_value;
+                    } else {
+                        // make this a null pointer
+                        ZigType *usize = g->builtin_types.entry_usize;
+                        const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type),
+                                get_llvm_type(g, const_val->type));
+                        return const_val->global_refs->llvm_value;
+                    }
                 }
                 size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index;
                 LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, elem_index);
@@ -6955,7 +6963,9 @@ check: switch (const_val->special) {
                     case ConstArraySpecialUndef:
                         return LLVMGetUndef(get_llvm_type(g, type_entry));
                     case ConstArraySpecialNone: {
-                        LLVMValueRef *values = allocate<LLVMValueRef>(len);
+                        uint64_t extra_len_from_null = type_entry->data.array.is_null_terminated ? 1 : 0;
+                        uint64_t full_len = len + extra_len_from_null;
+                        LLVMValueRef *values = allocate<LLVMValueRef>(full_len);
                         LLVMTypeRef element_type_ref = get_llvm_type(g, type_entry->data.array.child_type);
                         bool make_unnamed_struct = false;
                         for (uint64_t i = 0; i < len; i += 1) {
@@ -6964,15 +6974,19 @@ check: switch (const_val->special) {
                             values[i] = val;
                             make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, elem_value->type, val);
                         }
+                        if (type_entry->data.array.is_null_terminated) {
+                            values[len] = LLVMConstNull(element_type_ref);
+                        }
                         if (make_unnamed_struct) {
-                            return LLVMConstStruct(values, len, true);
+                            return LLVMConstStruct(values, full_len, true);
                         } else {
-                            return LLVMConstArray(element_type_ref, values, (unsigned)len);
+                            return LLVMConstArray(element_type_ref, values, (unsigned)full_len);
                         }
                     }
                     case ConstArraySpecialBuf: {
                         Buf *buf = const_val->data.x_array.data.s_buf;
-                        return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), true);
+                        return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf),
+                                !type_entry->data.array.is_null_terminated);
                     }
                 }
                 zig_unreachable();
@@ -9092,7 +9106,7 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
         this_val->data.x_struct.fields = alloc_const_vals_ptrs(2);
 
         ConstExprValue *name_field = this_val->data.x_struct.fields[0];
-        ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name);
+        ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name)->data.x_ptr.data.ref.pointee;
         init_const_slice(g, name_field, name_array_val, 0, buf_len(&test_fn_entry->symbol_name), true);
 
         ConstExprValue *fn_field = this_val->data.x_struct.fields[1];
@@ -10415,6 +10429,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
     g->external_prototypes.init(8);
     g->string_literals_table.init(16);
     g->type_info_cache.init(32);
+    g->one_possible_values.init(32);
     g->is_test_build = is_test_build;
     g->is_single_threaded = false;
     buf_resize(&g->global_asm, 0);
src/ir.cpp
@@ -66,6 +66,8 @@ enum ConstCastResultId {
     ConstCastResultIdUnresolvedInferredErrSet,
     ConstCastResultIdAsyncAllocatorType,
     ConstCastResultIdBadAllowsZero,
+    ConstCastResultIdArrayChild,
+    ConstCastResultIdBadNullTermArrays,
 };
 
 struct ConstCastOnly;
@@ -87,7 +89,9 @@ struct ConstCastErrUnionErrSetMismatch;
 struct ConstCastErrUnionPayloadMismatch;
 struct ConstCastErrSetMismatch;
 struct ConstCastTypeMismatch;
+struct ConstCastArrayMismatch;
 struct ConstCastBadAllowsZero;
+struct ConstCastBadNullTermArrays;
 
 struct ConstCastOnly {
     ConstCastResultId id;
@@ -99,11 +103,13 @@ struct ConstCastOnly {
         ConstCastErrUnionPayloadMismatch *error_union_payload;
         ConstCastErrUnionErrSetMismatch *error_union_error_set;
         ConstCastTypeMismatch *type_mismatch;
+        ConstCastArrayMismatch *array_mismatch;
         ConstCastOnly *return_type;
         ConstCastOnly *null_wrap_ptr_child;
         ConstCastArg fn_arg;
         ConstCastArgNoAlias arg_no_alias;
         ConstCastBadAllowsZero *bad_allows_zero;
+        ConstCastBadNullTermArrays *bad_null_term_arrays;
     } data;
 };
 
@@ -130,6 +136,12 @@ struct ConstCastSliceMismatch {
     ZigType *actual_child;
 };
 
+struct ConstCastArrayMismatch {
+    ConstCastOnly child;
+    ZigType *wanted_child;
+    ZigType *actual_child;
+};
+
 struct ConstCastErrUnionErrSetMismatch {
     ConstCastOnly child;
     ZigType *wanted_err_set;
@@ -151,6 +163,12 @@ struct ConstCastBadAllowsZero {
     ZigType *actual_type;
 };
 
+struct ConstCastBadNullTermArrays {
+    ConstCastOnly child;
+    ZigType *wanted_type;
+    ZigType *actual_type;
+};
+
 
 static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
 static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
@@ -217,10 +235,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c
         case OnePossibleValueInvalid:
             zig_unreachable();
         case OnePossibleValueYes:
-            result = create_const_vals(1);
-            result->type = const_val->type->data.pointer.child_type;
-            result->special = ConstValSpecialStatic;
-            return result;
+            return get_the_one_possible_value(g, const_val->type->data.pointer.child_type);
         case OnePossibleValueNo:
             break;
     }
@@ -233,8 +248,13 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c
             break;
         case ConstPtrSpecialBaseArray: {
             ConstExprValue *array_val = const_val->data.x_ptr.data.base_array.array_val;
-            expand_undef_array(g, array_val);
-            result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index];
+            if (const_val->data.x_ptr.data.base_array.elem_index == array_val->type->data.array.len) {
+                assert(array_val->type->data.array.is_null_terminated);
+                result = get_null_value(array_val->type->data.array.child_type);
+            } else {
+                expand_undef_array(g, array_val);
+                result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index];
+            }
             break;
         }
         case ConstPtrSpecialBaseStruct: {
@@ -282,20 +302,20 @@ static bool slice_is_const(ZigType *type) {
 
 // This function returns true when you can change the type of a ConstExprValue and the
 // value remains meaningful.
-static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) {
-    if (a == b)
+static bool types_have_same_zig_comptime_repr(ZigType *expected, ZigType *actual) {
+    if (expected == actual)
         return true;
 
-    if (get_codegen_ptr_type(a) != nullptr && get_codegen_ptr_type(b) != nullptr)
+    if (get_codegen_ptr_type(expected) != nullptr && get_codegen_ptr_type(actual) != nullptr)
         return true;
 
-    if (is_opt_err_set(a) && is_opt_err_set(b))
+    if (is_opt_err_set(expected) && is_opt_err_set(actual))
         return true;
 
-    if (a->id != b->id)
+    if (expected->id != actual->id)
         return false;
 
-    switch (a->id) {
+    switch (expected->id) {
         case ZigTypeIdInvalid:
         case ZigTypeIdUnreachable:
             zig_unreachable();
@@ -314,12 +334,11 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) {
         case ZigTypeIdAnyFrame:
             return true;
         case ZigTypeIdFloat:
-            return a->data.floating.bit_count == b->data.floating.bit_count;
+            return expected->data.floating.bit_count == actual->data.floating.bit_count;
         case ZigTypeIdInt:
-            return a->data.integral.is_signed == b->data.integral.is_signed;
+            return expected->data.integral.is_signed == actual->data.integral.is_signed;
         case ZigTypeIdStruct:
-            return is_slice(a) && is_slice(b);
-        case ZigTypeIdArray:
+            return is_slice(expected) && is_slice(actual);
         case ZigTypeIdOptional:
         case ZigTypeIdErrorUnion:
         case ZigTypeIdEnum:
@@ -329,6 +348,10 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) {
         case ZigTypeIdVector:
         case ZigTypeIdFnFrame:
             return false;
+        case ZigTypeIdArray:
+            return expected->data.array.len == actual->data.array.len &&
+                expected->data.array.child_type == actual->data.array.child_type &&
+                (!expected->data.array.is_null_terminated || actual->data.array.is_null_terminated);
     }
     zig_unreachable();
 }
@@ -1299,12 +1322,6 @@ static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, Scope *scope, AstNo
     return instruction;
 }
 
-static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) {
-    IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
-    init_const_c_str_lit(irb->codegen, &const_instruction->base.value, str);
-    return &const_instruction->base;
-}
-
 static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id,
         IrInstruction *op1, IrInstruction *op2, bool safety_check_on)
 {
@@ -6932,11 +6949,7 @@ static IrInstruction *ir_gen_enum_literal(IrBuilder *irb, Scope *scope, AstNode
 static IrInstruction *ir_gen_string_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
     assert(node->type == NodeTypeStringLiteral);
 
-    if (node->data.string_literal.c) {
-        return ir_build_const_c_str_lit(irb, scope, node, node->data.string_literal.buf);
-    } else {
-        return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf);
-    }
+    return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf);
 }
 
 static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *node) {
@@ -8662,7 +8675,15 @@ ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprVal
     assert(val != nullptr);
     assert(const_val->type->id == ZigTypeIdPointer);
     ZigType *expected_type = const_val->type->data.pointer.child_type;
-    if (!types_have_same_zig_comptime_repr(val->type, expected_type)) {
+    switch (type_has_one_possible_value(codegen, expected_type)) {
+        case OnePossibleValueInvalid:
+            return nullptr;
+        case OnePossibleValueNo:
+            break;
+        case OnePossibleValueYes:
+            return get_the_one_possible_value(codegen, expected_type);
+    }
+    if (!types_have_same_zig_comptime_repr(expected_type, val->type)) {
         if ((err = eval_comptime_ptr_reinterpret(ira, codegen, source_node, const_val)))
             return nullptr;
         return const_ptr_pointee_unchecked(codegen, const_val);
@@ -9876,6 +9897,35 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
         }
     }
 
+    // arrays
+    if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdArray &&
+        wanted_type->data.array.len == actual_type->data.array.len)
+    {
+        ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.array.child_type,
+                actual_type->data.array.child_type, source_node, wanted_is_mutable);
+        if (child.id == ConstCastResultIdInvalid)
+            return child;
+        if (child.id != ConstCastResultIdOk) {
+            result.id = ConstCastResultIdArrayChild;
+            result.data.array_mismatch = allocate_nonzero<ConstCastArrayMismatch>(1);
+            result.data.array_mismatch->child = child;
+            result.data.array_mismatch->wanted_child = wanted_type->data.array.child_type;
+            result.data.array_mismatch->actual_child = actual_type->data.array.child_type;
+            return result;
+        }
+        bool ok_null_terminated = !wanted_type->data.array.is_null_terminated ||
+            actual_type->data.array.is_null_terminated;
+        if (!ok_null_terminated) {
+            result.id = ConstCastResultIdBadNullTermArrays;
+            result.data.bad_null_term_arrays = allocate_nonzero<ConstCastBadNullTermArrays>(1);
+            result.data.bad_null_term_arrays->child = child;
+            result.data.bad_null_term_arrays->wanted_type = wanted_type;
+            result.data.bad_null_term_arrays->actual_type = actual_type;
+            return result;
+        }
+        return result;
+    }
+
     // slice const
     if (is_slice(wanted_type) && is_slice(actual_type)) {
         ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index]->type_entry;
@@ -10692,6 +10742,42 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
             continue;
         }
 
+
+        // *[N]T and *[M]T
+        if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle &&
+                cur_type->data.pointer.child_type->id == ZigTypeIdArray &&
+            prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle &&
+                prev_type->data.pointer.child_type->id == ZigTypeIdArray &&
+            (cur_type->data.pointer.is_const || !prev_type->data.pointer.is_const ||
+                prev_type->data.pointer.child_type->data.array.len == 0) &&
+            (cur_type->data.pointer.child_type->data.array.is_null_terminated ||
+                !prev_type->data.pointer.child_type->data.array.is_null_terminated) &&
+            types_match_const_cast_only(ira,
+                cur_type->data.pointer.child_type->data.array.child_type,
+                prev_type->data.pointer.child_type->data.array.child_type,
+                source_node, !cur_type->data.pointer.is_const).id == ConstCastResultIdOk)
+        {
+            prev_inst = cur_inst;
+            convert_to_const_slice = true;
+            continue;
+        }
+        if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle &&
+                prev_type->data.pointer.child_type->id == ZigTypeIdArray &&
+            cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle &&
+                cur_type->data.pointer.child_type->id == ZigTypeIdArray &&
+            (prev_type->data.pointer.is_const || !cur_type->data.pointer.is_const ||
+                cur_type->data.pointer.child_type->data.array.len == 0) &&
+            (prev_type->data.pointer.child_type->data.array.is_null_terminated ||
+                !cur_type->data.pointer.child_type->data.array.is_null_terminated) &&
+            types_match_const_cast_only(ira,
+                prev_type->data.pointer.child_type->data.array.child_type,
+                cur_type->data.pointer.child_type->data.array.child_type,
+                source_node, !prev_type->data.pointer.is_const).id == ConstCastResultIdOk)
+        {
+            convert_to_const_slice = true;
+            continue;
+        }
+
         // [N]T to []T
         if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) &&
             (cur_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const ||
@@ -10740,16 +10826,33 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
     free(errors);
 
     if (convert_to_const_slice) {
-        assert(prev_inst->value.type->id == ZigTypeIdArray);
-        ZigType *ptr_type = get_pointer_to_type_extra(
-                ira->codegen, prev_inst->value.type->data.array.child_type,
-                true, false, PtrLenUnknown,
-                0, 0, 0, false);
-        ZigType *slice_type = get_slice_type(ira->codegen, ptr_type);
-        if (err_set_type != nullptr) {
-            return get_error_union_type(ira->codegen, err_set_type, slice_type);
+        if (prev_inst->value.type->id == ZigTypeIdArray) {
+            ZigType *ptr_type = get_pointer_to_type_extra(
+                    ira->codegen, prev_inst->value.type->data.array.child_type,
+                    true, false, PtrLenUnknown,
+                    0, 0, 0, false);
+            ZigType *slice_type = get_slice_type(ira->codegen, ptr_type);
+            if (err_set_type != nullptr) {
+                return get_error_union_type(ira->codegen, err_set_type, slice_type);
+            } else {
+                return slice_type;
+            }
+        } else if (prev_inst->value.type->id == ZigTypeIdPointer) {
+            ZigType *array_type = prev_inst->value.type->data.pointer.child_type;
+            src_assert(array_type->id == ZigTypeIdArray, source_node);
+            ZigType *ptr_type = get_pointer_to_type_extra(
+                    ira->codegen, array_type->data.array.child_type,
+                    prev_inst->value.type->data.pointer.is_const, false,
+                    array_type->data.array.is_null_terminated ? PtrLenNull : PtrLenUnknown,
+                    0, 0, 0, false);
+            ZigType *slice_type = get_slice_type(ira->codegen, ptr_type);
+            if (err_set_type != nullptr) {
+                return get_error_union_type(ira->codegen, err_set_type, slice_type);
+            } else {
+                return slice_type;
+            }
         } else {
-            return slice_type;
+            zig_unreachable();
         }
     } else if (err_set_type != nullptr) {
         if (prev_inst->value.type->id == ZigTypeIdErrorSet) {
@@ -10970,7 +11073,6 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira,
             result->value.data.x_ptr.mut = value->value.data.x_ptr.mut;
             result->value.data.x_ptr.data.base_array.array_val = pointee;
             result->value.data.x_ptr.data.base_array.elem_index = 0;
-            result->value.data.x_ptr.data.base_array.is_cstr = false;
             return result;
         }
     }
@@ -10982,31 +11084,31 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira,
 }
 
 static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,
-        IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc)
+        IrInstruction *array_ptr, ZigType *wanted_type, ResultLoc *result_loc)
 {
     Error err;
 
-    if ((err = type_resolve(ira->codegen, value->value.type->data.pointer.child_type,
+    if ((err = type_resolve(ira->codegen, array_ptr->value.type->data.pointer.child_type,
                     ResolveStatusAlignmentKnown)))
     {
         return ira->codegen->invalid_instruction;
     }
 
-    wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value.type));
+    wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, array_ptr->value.type));
 
-    if (instr_is_comptime(value)) {
-        ConstExprValue *pointee = const_ptr_pointee(ira, ira->codegen, &value->value, source_instr->source_node);
+    if (instr_is_comptime(array_ptr)) {
+        ConstExprValue *pointee = const_ptr_pointee(ira, ira->codegen, &array_ptr->value, source_instr->source_node);
         if (pointee == nullptr)
             return ira->codegen->invalid_instruction;
         if (pointee->special != ConstValSpecialRuntime) {
-            assert(value->value.type->id == ZigTypeIdPointer);
-            ZigType *array_type = value->value.type->data.pointer.child_type;
+            assert(array_ptr->value.type->id == ZigTypeIdPointer);
+            ZigType *array_type = array_ptr->value.type->data.pointer.child_type;
             assert(is_slice(wanted_type));
             bool is_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const;
 
             IrInstruction *result = ir_const(ira, source_instr, wanted_type);
             init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const);
-            result->value.data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = value->value.data.x_ptr.mut;
+            result->value.data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr->value.data.x_ptr.mut;
             result->value.type = wanted_type;
             return result;
         }
@@ -11018,7 +11120,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
     if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
         return result_loc_inst;
     }
-    return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, value, result_loc_inst);
+    return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, array_ptr, result_loc_inst);
 }
 
 static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) {
@@ -12483,6 +12585,8 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
         case ConstCastResultIdFnArgNoAlias: // TODO
         case ConstCastResultIdUnresolvedInferredErrSet: // TODO
         case ConstCastResultIdAsyncAllocatorType: // TODO
+        case ConstCastResultIdArrayChild: // TODO
+        case ConstCastResultIdBadNullTermArrays: // TODO
             break;
     }
 }
@@ -12795,7 +12899,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
         return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type);
     }
 
-
     // cast from [N]T to []const T
     // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this
     if (is_slice(wanted_type) && actual_type->id == ZigTypeIdArray) {
@@ -12834,23 +12937,46 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
         }
     }
 
-    // *[N]T to [*]T and [*c]T
-    if (wanted_type->id == ZigTypeIdPointer &&
-        (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC) &&
+    // *[N]T to ?[]const T
+    if (wanted_type->id == ZigTypeIdOptional &&
+        is_slice(wanted_type->data.maybe.child_type) &&
         actual_type->id == ZigTypeIdPointer &&
         actual_type->data.pointer.ptr_len == PtrLenSingle &&
         actual_type->data.pointer.child_type->id == ZigTypeIdArray)
     {
-        if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
+        IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value, nullptr);
+        if (type_is_invalid(cast1->value.type))
             return ira->codegen->invalid_instruction;
-        if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
+
+        IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc);
+        if (type_is_invalid(cast2->value.type))
             return ira->codegen->invalid_instruction;
-        if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) &&
-            types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
-                actual_type->data.pointer.child_type->data.array.child_type, source_node,
-                !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
+
+        return cast2;
+    }
+
+    // *[N]T to [*]T and [*c]T
+    if (wanted_type->id == ZigTypeIdPointer &&
+        (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC ||
+            wanted_type->data.pointer.ptr_len == PtrLenNull) &&
+        actual_type->id == ZigTypeIdPointer &&
+        actual_type->data.pointer.ptr_len == PtrLenSingle &&
+        actual_type->data.pointer.child_type->id == ZigTypeIdArray)
+    {
+        if (wanted_type->data.pointer.ptr_len != PtrLenNull ||
+            actual_type->data.pointer.child_type->data.array.is_null_terminated)
         {
-            return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type);
+            if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
+                return ira->codegen->invalid_instruction;
+            if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
+                return ira->codegen->invalid_instruction;
+            if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) &&
+                types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
+                    actual_type->data.pointer.child_type->data.array.child_type, source_node,
+                    !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
+            {
+                return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type);
+            }
         }
     }
 
@@ -14544,8 +14670,6 @@ static bool ok_float_op(IrBinOp op) {
 }
 
 static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) {
-    if (lhs_type->id != ZigTypeIdPointer)
-        return false;
     switch (op) {
         case IrBinOpAdd:
         case IrBinOpSub:
@@ -14553,15 +14677,17 @@ static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) {
         default:
             return false;
     }
+    if (lhs_type->id != ZigTypeIdPointer)
+        return false;
     switch (lhs_type->data.pointer.ptr_len) {
         case PtrLenSingle:
-            return false;
+            return lhs_type->data.pointer.child_type->id == ZigTypeIdArray;
         case PtrLenUnknown:
         case PtrLenNull:
         case PtrLenC:
-            break;
+            return true;
     }
-    return true;
+    zig_unreachable();
 }
 
 static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) {
@@ -14823,6 +14949,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
     if (!op2_val)
         return ira->codegen->invalid_instruction;
 
+    bool is_null_terminated = false;
     ConstExprValue *op1_array_val;
     size_t op1_array_index;
     size_t op1_array_end;
@@ -14834,13 +14961,14 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
         op1_array_end = op1_type->data.array.len;
     } else if (op1_type->id == ZigTypeIdPointer &&
         op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 &&
-        op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray &&
-        op1_val->data.x_ptr.data.base_array.is_cstr)
+        op1_type->data.pointer.ptr_len == PtrLenNull &&
+        op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray)
     {
         child_type = op1_type->data.pointer.child_type;
         op1_array_val = op1_val->data.x_ptr.data.base_array.array_val;
         op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index;
-        op1_array_end = op1_array_val->type->data.array.len - 1;
+        op1_array_end = op1_array_val->type->data.array.len;
+        is_null_terminated = true;
     } else if (is_slice(op1_type)) {
         ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index]->type_entry;
         child_type = ptr_type->data.pointer.child_type;
@@ -14850,9 +14978,20 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
         op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;
         ConstExprValue *len_val = op1_val->data.x_struct.fields[slice_len_index];
         op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint);
+    } else if (op1_type->id == ZigTypeIdPointer && op1_type->data.pointer.ptr_len == PtrLenSingle &&
+            op1_type->data.pointer.child_type->id == ZigTypeIdArray)
+    {
+        ZigType *array_type = op1_type->data.pointer.child_type;
+        child_type = array_type->data.array.child_type;
+        op1_array_val = const_ptr_pointee(ira, ira->codegen, op1_val, op1->source_node);
+        if (op1_array_val == nullptr)
+            return ira->codegen->invalid_instruction;
+        op1_array_index = 0;
+        op1_array_end = array_type->data.array.len;
+        is_null_terminated = is_null_terminated || array_type->data.array.is_null_terminated;
     } else {
         ir_add_error(ira, op1,
-            buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op1->value.type->name)));
+            buf_sprintf("expected array, found '%s'", buf_ptr(&op1->value.type->name)));
         return ira->codegen->invalid_instruction;
     }
 
@@ -14866,14 +15005,14 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
         op2_array_index = 0;
         op2_array_end = op2_array_val->type->data.array.len;
     } else if (op2_type->id == ZigTypeIdPointer &&
-        op2_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 &&
-        op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray &&
-        op2_val->data.x_ptr.data.base_array.is_cstr)
+        op2_type->data.pointer.ptr_len == PtrLenNull &&
+        op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray)
     {
-        op2_type_valid = child_type == ira->codegen->builtin_types.entry_u8;
+        op2_type_valid = op2_type->data.pointer.child_type == child_type;
         op2_array_val = op2_val->data.x_ptr.data.base_array.array_val;
         op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index;
-        op2_array_end = op2_array_val->type->data.array.len - 1;
+        op2_array_end = op2_array_val->type->data.array.len;
+        is_null_terminated = true;
     } else if (is_slice(op2_type)) {
         ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index]->type_entry;
         op2_type_valid = ptr_type->data.pointer.child_type == child_type;
@@ -14883,6 +15022,17 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
         op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;
         ConstExprValue *len_val = op2_val->data.x_struct.fields[slice_len_index];
         op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint);
+    } else if (op2_type->id == ZigTypeIdPointer && op2_type->data.pointer.ptr_len == PtrLenSingle &&
+            op2_type->data.pointer.child_type->id == ZigTypeIdArray)
+    {
+        ZigType *array_type = op2_type->data.pointer.child_type;
+        op2_type_valid = array_type->data.array.child_type == child_type;
+        op2_array_val = const_ptr_pointee(ira, ira->codegen, op2_val, op2->source_node);
+        if (op2_array_val == nullptr)
+            return ira->codegen->invalid_instruction;
+        op2_array_index = 0;
+        op2_array_end = array_type->data.array.len;
+        is_null_terminated = is_null_terminated || array_type->data.array.is_null_terminated;
     } else {
         ir_add_error(ira, op2,
             buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name)));
@@ -14905,6 +15055,14 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
         result->value.type = get_array_type(ira->codegen, child_type, new_len, false);
 
         out_array_val = out_val;
+    } else if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) {
+        out_array_val = create_const_vals(1);
+        out_array_val->special = ConstValSpecialStatic;
+        out_array_val->type = get_array_type(ira->codegen, child_type, new_len, is_null_terminated);
+
+        out_val->data.x_ptr.special = ConstPtrSpecialRef;
+        out_val->data.x_ptr.data.ref.pointee = out_array_val;
+        out_val->type = get_pointer_to_type(ira->codegen, out_array_val->type, true);
     } else if (is_slice(op1_type) || is_slice(op2_type)) {
         ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, child_type,
                 true, false, PtrLenUnknown, 0, 0, 0, false);
@@ -14925,22 +15083,20 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
         out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic;
         bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len);
     } else {
-        new_len += 1; // null byte
-
-        // TODO make this `[*]null T` instead of `[*]T`
-        result->value.type = get_pointer_to_type_extra(ira->codegen, child_type, true, false, PtrLenUnknown, 0, 0, 0, false);
+        result->value.type = get_pointer_to_type_extra(ira->codegen, child_type, true, false, PtrLenNull,
+                0, 0, 0, false);
 
         out_array_val = create_const_vals(1);
         out_array_val->special = ConstValSpecialStatic;
         out_array_val->type = get_array_type(ira->codegen, child_type, new_len, false);
         out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
-        out_val->data.x_ptr.data.base_array.is_cstr = true;
         out_val->data.x_ptr.data.base_array.array_val = out_array_val;
         out_val->data.x_ptr.data.base_array.elem_index = 0;
     }
 
     if (op1_array_val->data.x_array.special == ConstArraySpecialUndef &&
-        op2_array_val->data.x_array.special == ConstArraySpecialUndef) {
+        op2_array_val->data.x_array.special == ConstArraySpecialUndef)
+    {
         out_array_val->data.x_array.special = ConstArraySpecialUndef;
         return result;
     }
@@ -14978,20 +15134,34 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *
     if (type_is_invalid(op2->value.type))
         return ira->codegen->invalid_instruction;
 
-    ConstExprValue *array_val = ir_resolve_const(ira, op1, UndefBad);
-    if (!array_val)
+    bool want_ptr_to_array = false;
+    ZigType *array_type;
+    ConstExprValue *array_val;
+    if (op1->value.type->id == ZigTypeIdArray) {
+        array_type = op1->value.type;
+        array_val = ir_resolve_const(ira, op1, UndefOk);
+        if (array_val == nullptr)
+            return ira->codegen->invalid_instruction;
+    } else if (op1->value.type->id == ZigTypeIdPointer && op1->value.type->data.pointer.ptr_len == PtrLenSingle &&
+        op1->value.type->data.pointer.child_type->id == ZigTypeIdArray)
+    {
+        array_type = op1->value.type->data.pointer.child_type;
+        IrInstruction *array_inst = ir_get_deref(ira, op1, op1, nullptr);
+        if (type_is_invalid(array_inst->value.type))
+            return ira->codegen->invalid_instruction;
+        array_val = ir_resolve_const(ira, array_inst, UndefOk);
+        if (array_val == nullptr)
+            return ira->codegen->invalid_instruction;
+        want_ptr_to_array = true;
+    } else {
+        ir_add_error(ira, op1, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value.type->name)));
         return ira->codegen->invalid_instruction;
+    }
 
     uint64_t mult_amt;
     if (!ir_resolve_usize(ira, op2, &mult_amt))
         return ira->codegen->invalid_instruction;
 
-    ZigType *array_type = op1->value.type;
-    if (array_type->id != ZigTypeIdArray) {
-        ir_add_error(ira, op1, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value.type->name)));
-        return ira->codegen->invalid_instruction;
-    }
-
     uint64_t old_array_len = array_type->data.array.len;
     uint64_t new_array_len;
 
@@ -15001,42 +15171,59 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *
     }
 
     ZigType *child_type = array_type->data.array.child_type;
+    ZigType *result_array_type = get_array_type(ira->codegen, child_type, new_array_len,
+            array_type->data.array.is_null_terminated);
 
-    IrInstruction *result = ir_const(ira, &instruction->base,
-        get_array_type(ira->codegen, child_type, new_array_len, false));
-    ConstExprValue *out_val = &result->value;
-    if (array_val->data.x_array.special == ConstArraySpecialUndef) {
-        out_val->data.x_array.special = ConstArraySpecialUndef;
-        return result;
-    }
+    IrInstruction *array_result;
+    if (array_val->special == ConstValSpecialUndef || array_val->data.x_array.special == ConstArraySpecialUndef) {
+        array_result = ir_const_undef(ira, &instruction->base, result_array_type);
+    } else {
+        array_result = ir_const(ira, &instruction->base, result_array_type);
+        ConstExprValue *out_val = &array_result->value;
 
-    switch (type_has_one_possible_value(ira->codegen, result->value.type)) {
-        case OnePossibleValueInvalid:
-            return ira->codegen->invalid_instruction;
-        case OnePossibleValueYes:
-            return result;
-        case OnePossibleValueNo:
-            break;
-    }
+        switch (type_has_one_possible_value(ira->codegen, result_array_type)) {
+            case OnePossibleValueInvalid:
+                return ira->codegen->invalid_instruction;
+            case OnePossibleValueYes:
+                goto skip_computation;
+            case OnePossibleValueNo:
+                break;
+        }
 
-    // TODO optimize the buf case
-    expand_undef_array(ira->codegen, array_val);
-    out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len);
+        // TODO optimize the buf case
+        expand_undef_array(ira->codegen, array_val);
+        size_t extra_null_term = array_type->data.array.is_null_terminated ? 1 : 0;
+        out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len + extra_null_term);
 
-    uint64_t i = 0;
-    for (uint64_t x = 0; x < mult_amt; x += 1) {
-        for (uint64_t y = 0; y < old_array_len; y += 1) {
+        uint64_t i = 0;
+        for (uint64_t x = 0; x < mult_amt; x += 1) {
+            for (uint64_t y = 0; y < old_array_len; y += 1) {
+                ConstExprValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i];
+                copy_const_val(elem_dest_val, &array_val->data.x_array.data.s_none.elements[y], false);
+                elem_dest_val->parent.id = ConstParentIdArray;
+                elem_dest_val->parent.data.p_array.array_val = out_val;
+                elem_dest_val->parent.data.p_array.elem_index = i;
+                i += 1;
+            }
+        }
+        assert(i == new_array_len);
+
+        if (array_type->data.array.is_null_terminated) {
+            ConstExprValue *null_value = get_null_value(array_type->data.array.child_type);
             ConstExprValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i];
-            copy_const_val(elem_dest_val, &array_val->data.x_array.data.s_none.elements[y], false);
+            copy_const_val(elem_dest_val, null_value, false);
             elem_dest_val->parent.id = ConstParentIdArray;
             elem_dest_val->parent.data.p_array.array_val = out_val;
             elem_dest_val->parent.data.p_array.elem_index = i;
             i += 1;
         }
     }
-    assert(i == new_array_len);
-
-    return result;
+skip_computation:
+    if (want_ptr_to_array) {
+        return ir_get_ref(ira, &instruction->base, array_result, true, false);
+    } else {
+        return array_result;
+    }
 }
 
 static IrInstruction *ir_analyze_instruction_merge_err_sets(IrAnalyze *ira,
@@ -17309,6 +17496,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
     assert(out_val->type != nullptr);
 
     ConstExprValue *pointee = const_ptr_pointee_unchecked(codegen, ptr_val);
+    src_assert(pointee->type != nullptr, source_node);
 
     if ((err = type_resolve(codegen, pointee->type, ResolveStatusSizeKnown)))
         return ErrorSemanticAnalyzeFail;
@@ -17319,7 +17507,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
     size_t dst_size = type_size(codegen, out_val->type);
 
     if (dst_size <= src_size) {
-        if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) {
+        if (src_size == dst_size && types_have_same_zig_comptime_repr(out_val->type, pointee->type)) {
             copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar);
             return ErrorNone;
         }
@@ -18070,6 +18258,12 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
         uint64_t index = bigint_as_u64(&casted_elem_index->value.data.x_bigint);
         if (array_type->id == ZigTypeIdArray) {
             uint64_t array_len = array_type->data.array.len;
+            if (index == array_len && array_type->data.array.is_null_terminated) {
+                ZigType *elem_type = array_type->data.array.child_type;
+                IrInstruction *null_element = ir_const(ira, &elem_ptr_instruction->base, elem_type);
+                null_element->value = *get_null_value(elem_type);
+                return ir_get_ref(ira, &elem_ptr_instruction->base, null_element, true, false);
+            }
             if (index >= array_len) {
                 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
                     buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64,
@@ -18203,7 +18397,11 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
                             {
                                 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index;
                                 new_index = offset + index;
-                                mem_size = array_ptr_val->data.x_ptr.data.base_array.array_val->type->data.array.len;
+                                ZigType *array_type = array_ptr_val->data.x_ptr.data.base_array.array_val->type;
+                                mem_size = array_type->data.array.len;
+                                if (array_type->data.array.is_null_terminated) {
+                                    mem_size += 1;
+                                }
                                 old_size = mem_size - offset;
 
                                 assert(array_ptr_val->data.x_ptr.data.base_array.array_val);
@@ -18212,8 +18410,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
                                 out_val->data.x_ptr.data.base_array.array_val =
                                     array_ptr_val->data.x_ptr.data.base_array.array_val;
                                 out_val->data.x_ptr.data.base_array.elem_index = new_index;
-                                out_val->data.x_ptr.data.base_array.is_cstr =
-                                    array_ptr_val->data.x_ptr.data.base_array.is_cstr;
 
                                 break;
                             }
@@ -18277,8 +18473,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
                                 out_val->data.x_ptr.data.base_array.array_val =
                                     ptr_field->data.x_ptr.data.base_array.array_val;
                                 out_val->data.x_ptr.data.base_array.elem_index = new_index;
-                                out_val->data.x_ptr.data.base_array.is_cstr =
-                                    ptr_field->data.x_ptr.data.base_array.is_cstr;
                                 break;
                             }
                         case ConstPtrSpecialBaseStruct:
@@ -19550,7 +19744,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
     ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type,
             ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false);
 
-    bool same_comptime_repr = types_have_same_zig_comptime_repr(type_entry, child_type);
+    bool same_comptime_repr = types_have_same_zig_comptime_repr(child_type, type_entry);
 
     if (instr_is_comptime(base_ptr)) {
         ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);
@@ -20685,7 +20879,7 @@ static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruct
             return ira->codegen->invalid_instruction;
         ErrorTableEntry *err = casted_value->value.data.x_err_set;
         if (!err->cached_error_name_val) {
-            ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name);
+            ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name)->data.x_ptr.data.ref.pointee;
             err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true);
         }
         IrInstruction *result = ir_const(ira, &instruction->base, nullptr);
@@ -20714,7 +20908,7 @@ static IrInstruction *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrIns
         if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusZeroBitsKnown)))
             return ira->codegen->invalid_instruction;
         TypeEnumField *field = find_enum_field_by_tag(target->value.type, &target->value.data.x_bigint);
-        ConstExprValue *array_val = create_const_str_lit(ira->codegen, field->name);
+        ConstExprValue *array_val = create_const_str_lit(ira->codegen, field->name)->data.x_ptr.data.ref.pointee;
         IrInstruction *result = ir_const(ira, &instruction->base, nullptr);
         init_const_slice(ira->codegen, &result->value, array_val, 0, buf_len(field->name), true);
         return result;
@@ -21019,7 +21213,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
         declaration_val->type = type_info_declaration_type;
 
         ConstExprValue **inner_fields = alloc_const_vals_ptrs(3);
-        ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key);
+        ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key)->data.x_ptr.data.ref.pointee;
         init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(curr_entry->key), true);
         inner_fields[1]->special = ConstValSpecialStatic;
         inner_fields[1]->type = ira->codegen->builtin_types.entry_bool;
@@ -21122,7 +21316,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
                     fn_decl_fields[6]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));
                     if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) {
                         fn_decl_fields[6]->data.x_optional = create_const_vals(1);
-                        ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name);
+                        ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name)->data.x_ptr.data.ref.pointee;
                         init_const_slice(ira->codegen, fn_decl_fields[6]->data.x_optional, lib_name, 0,
                                 buf_len(fn_node->lib_name), true);
                     } else {
@@ -21149,7 +21343,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
                         ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index);
                         ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index];
                         ConstExprValue *arg_name = create_const_str_lit(ira->codegen,
-                                buf_create_from_str(arg_var->name));
+                                buf_create_from_str(arg_var->name))->data.x_ptr.data.ref.pointee;
                         init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, strlen(arg_var->name), true);
                         fn_arg_name_val->parent.id = ConstParentIdArray;
                         fn_arg_name_val->parent.data.p_array.array_val = fn_arg_name_array;
@@ -21294,7 +21488,7 @@ static void make_enum_field_val(IrAnalyze *ira, ConstExprValue *enum_field_val,
     inner_fields[1]->special = ConstValSpecialStatic;
     inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int;
 
-    ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name);
+    ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name)->data.x_ptr.data.ref.pointee;
     init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(enum_field->name), true);
 
     bigint_init_bigint(&inner_fields[1]->data.x_bigint, &enum_field->value);
@@ -21560,7 +21754,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
                     if (error->cached_error_name_val != nullptr)
                         name = error->cached_error_name_val;
                     if (name == nullptr)
-                        name = create_const_str_lit(ira->codegen, &error->name);
+                        name = create_const_str_lit(ira->codegen, &error->name)->data.x_ptr.data.ref.pointee;
                     init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(&error->name), true);
                     bigint_init_unsigned(&inner_fields[1]->data.x_bigint, error->value);
 
@@ -21666,7 +21860,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
                     inner_fields[2]->type = ira->codegen->builtin_types.entry_type;
                     inner_fields[2]->data.x_type = union_field->type_entry;
 
-                    ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name);
+                    ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee;
                     init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true);
 
                     union_field_val->data.x_struct.fields = inner_fields;
@@ -21752,7 +21946,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
                     inner_fields[2]->type = ira->codegen->builtin_types.entry_type;
                     inner_fields[2]->data.x_type = struct_field->type_entry;
 
-                    ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name);
+                    ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee;
                     init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true);
 
                     struct_field_val->data.x_struct.fields = inner_fields;
src/parser.cpp
@@ -1718,7 +1718,6 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
     if (string_lit != nullptr) {
         AstNode *res = ast_create_node(pc, NodeTypeStringLiteral, string_lit);
         res->data.string_literal.buf = token_buf(string_lit);
-        res->data.string_literal.c = string_lit->data.str_lit.is_c_str;
         return res;
     }
 
src/tokenizer.cpp
@@ -33,10 +33,10 @@
          '0': \
     case DIGIT_NON_ZERO
 
-#define ALPHA_EXCEPT_C \
+#define ALPHA \
          'a': \
     case 'b': \
-  /*case 'c':*/ \
+    case 'c': \
     case 'd': \
     case 'e': \
     case 'f': \
@@ -87,10 +87,6 @@
     case 'Y': \
     case 'Z'
 
-#define ALPHA \
-    ALPHA_EXCEPT_C: \
-    case 'c'
-
 #define SYMBOL_CHAR \
     ALPHA: \
     case DIGIT: \
@@ -180,7 +176,6 @@ static bool is_symbol_char(uint8_t c) {
 enum TokenizeState {
     TokenizeStateStart,
     TokenizeStateSymbol,
-    TokenizeStateSymbolFirstC,
     TokenizeStateZero, // "0", which might lead to "0x"
     TokenizeStateNumber, // "123", "0x123"
     TokenizeStateNumberDot,
@@ -279,7 +274,6 @@ static void set_token_id(Tokenize *t, Token *token, TokenId id) {
     } else if (id == TokenIdStringLiteral || id == TokenIdSymbol) {
         memset(&token->data.str_lit.str, 0, sizeof(Buf));
         buf_resize(&token->data.str_lit.str, 0);
-        token->data.str_lit.is_c_str = false;
     }
 }
 
@@ -429,12 +423,7 @@ void tokenize(Buf *buf, Tokenization *out) {
                 switch (c) {
                     case WHITESPACE:
                         break;
-                    case 'c':
-                        t.state = TokenizeStateSymbolFirstC;
-                        begin_token(&t, TokenIdSymbol);
-                        buf_append_char(&t.cur_tok->data.str_lit.str, c);
-                        break;
-                    case ALPHA_EXCEPT_C:
+                    case ALPHA:
                     case '_':
                         t.state = TokenizeStateSymbol;
                         begin_token(&t, TokenIdSymbol);
@@ -1007,19 +996,7 @@ void tokenize(Buf *buf, Tokenization *out) {
                 switch (c) {
                     case WHITESPACE:
                         break;
-                    case 'c':
-                        if (!t.cur_tok->data.str_lit.is_c_str) {
-                            t.pos -= 1;
-                            end_token(&t);
-                            t.state = TokenizeStateStart;
-                            break;
-                        }
-                        t.state = TokenizeStateLineStringContinueC;
-                        break;
                     case '\\':
-                        if (t.cur_tok->data.str_lit.is_c_str) {
-                            invalid_char_error(&t, c);
-                        }
                         t.state = TokenizeStateLineStringContinue;
                         break;
                     default:
@@ -1084,29 +1061,6 @@ void tokenize(Buf *buf, Tokenization *out) {
                         break;
                 }
                 break;
-            case TokenizeStateSymbolFirstC:
-                switch (c) {
-                    case '"':
-                        set_token_id(&t, t.cur_tok, TokenIdStringLiteral);
-                        t.cur_tok->data.str_lit.is_c_str = true;
-                        t.state = TokenizeStateString;
-                        break;
-                    case '\\':
-                        set_token_id(&t, t.cur_tok, TokenIdStringLiteral);
-                        t.cur_tok->data.str_lit.is_c_str = true;
-                        t.state = TokenizeStateSawBackslash;
-                        break;
-                    case SYMBOL_CHAR:
-                        t.state = TokenizeStateSymbol;
-                        buf_append_char(&t.cur_tok->data.str_lit.str, c);
-                        break;
-                    default:
-                        t.pos -= 1;
-                        end_token(&t);
-                        t.state = TokenizeStateStart;
-                        continue;
-                }
-                break;
             case TokenizeStateSawAtSign:
                 switch (c) {
                     case '"':
@@ -1544,7 +1498,6 @@ void tokenize(Buf *buf, Tokenization *out) {
             tokenize_error(&t, "unterminated character literal");
             break;
         case TokenizeStateSymbol:
-        case TokenizeStateSymbolFirstC:
         case TokenizeStateZero:
         case TokenizeStateNumber:
         case TokenizeStateFloatFraction:
src/tokenizer.hpp
@@ -149,7 +149,6 @@ struct TokenIntLit {
 
 struct TokenStrLit {
     Buf str;
-    bool is_c_str;
 };
 
 struct TokenCharLit {
src/translate_c.cpp
@@ -323,17 +323,9 @@ static AstNode *trans_create_node_bool(Context *c, bool value) {
     return bool_node;
 }
 
-static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) {
+static AstNode *trans_create_node_str_lit(Context *c, Buf *buf) {
     AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
     node->data.string_literal.buf = buf;
-    node->data.string_literal.c = true;
-    return node;
-}
-
-static AstNode *trans_create_node_str_lit_non_c(Context *c, Buf *buf) {
-    AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
-    node->data.string_literal.buf = buf;
-    node->data.string_literal.c = false;
     return node;
 }
 
@@ -632,7 +624,7 @@ static AstNode *qual_type_to_log2_int_ref(Context *c, const ZigClangQualType qt,
 //        zig_type_node
 
     AstNode *import_fn_call = trans_create_node_builtin_fn_call_str(c, "import");
-    import_fn_call->data.fn_call_expr.params.append(trans_create_node_str_lit_non_c(c, buf_create_from_str("std")));
+    import_fn_call->data.fn_call_expr.params.append(trans_create_node_str_lit(c, buf_create_from_str("std")));
     AstNode *inner_field_access = trans_create_node_field_access_str(c, import_fn_call, "math");
     AstNode *outer_field_access = trans_create_node_field_access_str(c, inner_field_access, "Log2Int");
     AstNode *log2int_fn_call = trans_create_node_fn_call_1(c, outer_field_access, zig_type_node);
@@ -3391,7 +3383,7 @@ static AstNode *trans_string_literal(Context *c, ResultUsed result_used, TransSc
         case ZigClangStringLiteral_StringKind_UTF8: {
             size_t str_len;
             const char *str_ptr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &str_len);
-            AstNode *node = trans_create_node_str_lit_c(c, buf_create_from_mem(str_ptr, str_len));
+            AstNode *node = trans_create_node_str_lit(c, buf_create_from_mem(str_ptr, str_len));
             return maybe_suppress_result(c, result_used, node);
         }
         case ZigClangStringLiteral_StringKind_UTF16:
@@ -4890,7 +4882,7 @@ static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok
             return trans_create_node_unsigned(c, tok->data.char_lit);
         case CTokIdStrLit:
             *tok_i += 1;
-            return trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit));
+            return trans_create_node_str_lit(c, buf_create_from_buf(&tok->data.str_lit));
         case CTokIdMinus:
             *tok_i += 1;
             return parse_ctok_num_lit(c, ctok, tok_i, true);
@@ -4937,7 +4929,7 @@ static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok
                 //    (dest)(x)
 
                 AstNode *import_builtin = trans_create_node_builtin_fn_call_str(c, "import");
-                import_builtin->data.fn_call_expr.params.append(trans_create_node_str_lit_non_c(c, buf_create_from_str("builtin")));
+                import_builtin->data.fn_call_expr.params.append(trans_create_node_str_lit(c, buf_create_from_str("builtin")));
                 AstNode *typeid_type = trans_create_node_field_access_str(c, import_builtin, "TypeId");
                 AstNode *typeid_pointer = trans_create_node_field_access_str(c, typeid_type, "Pointer");
                 AstNode *typeid_integer = trans_create_node_field_access_str(c, typeid_type, "Int");
src-self-hosted/codegen.zig
@@ -52,7 +52,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
         u32(c.ZIG_VERSION_MINOR),
         u32(c.ZIG_VERSION_PATCH),
     );
-    const flags = c"";
+    const flags = "";
     const runtime_version = 0;
     const compile_unit_file = llvm.CreateFile(
         dibuilder,
@@ -68,7 +68,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
         is_optimized,
         flags,
         runtime_version,
-        c"",
+        "",
         0,
         !comp.strip,
     ) orelse return error.OutOfMemory;
@@ -402,7 +402,7 @@ pub fn getHandleValue(ofile: *ObjectFile, ptr: *llvm.Value, ptr_type: *Type.Poin
     if (child_type.handleIsPtr()) {
         return ptr;
     }
-    return try renderLoad(ofile, ptr, ptr_type, c"");
+    return try renderLoad(ofile, ptr, ptr_type, "");
 }
 
 pub fn renderStoreUntyped(
src-self-hosted/compilation.zig
@@ -511,8 +511,8 @@ pub const Compilation = struct {
         comp.target_machine = llvm.CreateTargetMachine(
             comp.llvm_target,
             comp.llvm_triple.ptr(),
-            target_specific_cpu_args orelse c"",
-            target_specific_cpu_features orelse c"",
+            target_specific_cpu_args orelse "",
+            target_specific_cpu_features orelse "",
             opt_level,
             reloc_mode,
             llvm.CodeModelDefault,
src-self-hosted/ir.zig
@@ -331,7 +331,7 @@ pub const Inst = struct {
                 @intCast(c_uint, args.len),
                 llvm_cc,
                 fn_inline,
-                c"",
+                "",
             ) orelse error.OutOfMemory;
         }
     };
@@ -1410,7 +1410,7 @@ pub const Builder = struct {
         if (block.label) |label| {
             block_scope.incoming_values = std.ArrayList(*Inst).init(irb.arena());
             block_scope.incoming_blocks = std.ArrayList(*BasicBlock).init(irb.arena());
-            block_scope.end_block = try irb.createBasicBlock(parent_scope, c"BlockEnd");
+            block_scope.end_block = try irb.createBasicBlock(parent_scope, "BlockEnd");
             block_scope.is_comptime = try irb.buildConstBool(
                 parent_scope,
                 Span.token(block.lbrace),
@@ -1542,8 +1542,8 @@ pub const Builder = struct {
                 const defer_counts = irb.countDefers(scope, outer_scope);
                 const have_err_defers = defer_counts.error_exit != 0;
                 if (have_err_defers or irb.comp.have_err_ret_tracing) {
-                    const err_block = try irb.createBasicBlock(scope, c"ErrRetErr");
-                    const ok_block = try irb.createBasicBlock(scope, c"ErrRetOk");
+                    const err_block = try irb.createBasicBlock(scope, "ErrRetErr");
+                    const ok_block = try irb.createBasicBlock(scope, "ErrRetOk");
                     if (!have_err_defers) {
                         _ = try await (async irb.genDefersForBlock(scope, outer_scope, Scope.Defer.Kind.ScopeExit) catch unreachable);
                     }
@@ -1564,7 +1564,7 @@ pub const Builder = struct {
                         .is_comptime = err_is_comptime,
                     });
 
-                    const ret_stmt_block = try irb.createBasicBlock(scope, c"RetStmt");
+                    const ret_stmt_block = try irb.createBasicBlock(scope, "RetStmt");
 
                     try irb.setCursorAtEndAndAppendBlock(err_block);
                     if (have_err_defers) {
@@ -2530,7 +2530,7 @@ pub async fn gen(
     var irb = try Builder.init(comp, tree_scope, scope);
     errdefer irb.abort();
 
-    const entry_block = try irb.createBasicBlock(scope, c"Entry");
+    const entry_block = try irb.createBasicBlock(scope, "Entry");
     entry_block.ref(&irb); // Entry block gets a reference because we enter it to begin.
     try irb.setCursorAtEndAndAppendBlock(entry_block);
 
src-self-hosted/link.zig
@@ -55,7 +55,7 @@ pub async fn link(comp: *Compilation) !void {
 
     // even though we're calling LLD as a library it thinks the first
     // argument is its own exe name
-    try ctx.args.append(c"lld");
+    try ctx.args.append("lld");
 
     if (comp.haveLibC()) {
         ctx.libc = ctx.comp.override_libc orelse blk: {
@@ -145,7 +145,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
     //    lj->args.append("-T");
     //    lj->args.append(g->linker_script);
     //}
-    try ctx.args.append(c"--gc-sections");
+    try ctx.args.append("--gc-sections");
 
     //lj->args.append("-m");
     //lj->args.append(getLDMOption(&g->zig_target));
@@ -155,9 +155,9 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
     //Buf *soname = nullptr;
     if (ctx.comp.is_static) {
         if (ctx.comp.target.isArmOrThumb()) {
-            try ctx.args.append(c"-Bstatic");
+            try ctx.args.append("-Bstatic");
         } else {
-            try ctx.args.append(c"-static");
+            try ctx.args.append("-static");
         }
     }
     //} else if (shared) {
@@ -170,7 +170,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
     //    soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize "", buf_ptr(g->root_out_name), g->version_major);
     //}
 
-    try ctx.args.append(c"-o");
+    try ctx.args.append("-o");
     try ctx.args.append(ctx.out_file_path.ptr());
 
     if (ctx.link_in_crt) {
@@ -213,10 +213,10 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
     //}
 
     if (ctx.comp.haveLibC()) {
-        try ctx.args.append(c"-L");
+        try ctx.args.append("-L");
         try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.lib_dir.?)).ptr);
 
-        try ctx.args.append(c"-L");
+        try ctx.args.append("-L");
         try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.static_lib_dir.?)).ptr);
 
         if (!ctx.comp.is_static) {
@@ -225,7 +225,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
                 if (ctx.comp.target.getDynamicLinkerPath()) |dl| break :blk dl;
                 return error.LibCMissingDynamicLinker;
             };
-            try ctx.args.append(c"-dynamic-linker");
+            try ctx.args.append("-dynamic-linker");
             try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, dl)).ptr);
         }
     }
@@ -272,23 +272,23 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
     // libc dep
     if (ctx.comp.haveLibC()) {
         if (ctx.comp.is_static) {
-            try ctx.args.append(c"--start-group");
-            try ctx.args.append(c"-lgcc");
-            try ctx.args.append(c"-lgcc_eh");
-            try ctx.args.append(c"-lc");
-            try ctx.args.append(c"-lm");
-            try ctx.args.append(c"--end-group");
+            try ctx.args.append("--start-group");
+            try ctx.args.append("-lgcc");
+            try ctx.args.append("-lgcc_eh");
+            try ctx.args.append("-lc");
+            try ctx.args.append("-lm");
+            try ctx.args.append("--end-group");
         } else {
-            try ctx.args.append(c"-lgcc");
-            try ctx.args.append(c"--as-needed");
-            try ctx.args.append(c"-lgcc_s");
-            try ctx.args.append(c"--no-as-needed");
-            try ctx.args.append(c"-lc");
-            try ctx.args.append(c"-lm");
-            try ctx.args.append(c"-lgcc");
-            try ctx.args.append(c"--as-needed");
-            try ctx.args.append(c"-lgcc_s");
-            try ctx.args.append(c"--no-as-needed");
+            try ctx.args.append("-lgcc");
+            try ctx.args.append("--as-needed");
+            try ctx.args.append("-lgcc_s");
+            try ctx.args.append("--no-as-needed");
+            try ctx.args.append("-lc");
+            try ctx.args.append("-lm");
+            try ctx.args.append("-lgcc");
+            try ctx.args.append("--as-needed");
+            try ctx.args.append("-lgcc_s");
+            try ctx.args.append("--no-as-needed");
         }
     }
 
@@ -299,14 +299,14 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
     }
 
     if (ctx.comp.target != Target.Native) {
-        try ctx.args.append(c"--allow-shlib-undefined");
+        try ctx.args.append("--allow-shlib-undefined");
     }
 
     if (ctx.comp.target.getOs() == .zen) {
-        try ctx.args.append(c"-e");
-        try ctx.args.append(c"_start");
+        try ctx.args.append("-e");
+        try ctx.args.append("_start");
 
-        try ctx.args.append(c"--image-base=0x10000000");
+        try ctx.args.append("--image-base=0x10000000");
     }
 }
 
@@ -317,23 +317,23 @@ fn addPathJoin(ctx: *Context, dirname: []const u8, basename: []const u8) !void {
 }
 
 fn constructLinkerArgsCoff(ctx: *Context) !void {
-    try ctx.args.append(c"-NOLOGO");
+    try ctx.args.append("-NOLOGO");
 
     if (!ctx.comp.strip) {
-        try ctx.args.append(c"-DEBUG");
+        try ctx.args.append("-DEBUG");
     }
 
     switch (ctx.comp.target.getArch()) {
-        builtin.Arch.i386 => try ctx.args.append(c"-MACHINE:X86"),
-        builtin.Arch.x86_64 => try ctx.args.append(c"-MACHINE:X64"),
-        builtin.Arch.aarch64 => try ctx.args.append(c"-MACHINE:ARM"),
+        builtin.Arch.i386 => try ctx.args.append("-MACHINE:X86"),
+        builtin.Arch.x86_64 => try ctx.args.append("-MACHINE:X64"),
+        builtin.Arch.aarch64 => try ctx.args.append("-MACHINE:ARM"),
         else => return error.UnsupportedLinkArchitecture,
     }
 
     if (ctx.comp.windows_subsystem_windows) {
-        try ctx.args.append(c"/SUBSYSTEM:windows");
+        try ctx.args.append("/SUBSYSTEM:windows");
     } else if (ctx.comp.windows_subsystem_console) {
-        try ctx.args.append(c"/SUBSYSTEM:console");
+        try ctx.args.append("/SUBSYSTEM:console");
     }
 
     const is_library = ctx.comp.kind == Compilation.Kind.Lib;
@@ -367,14 +367,14 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
 
         // Visual C++ 2015 Conformance Changes
         // https://msdn.microsoft.com/en-us/library/bb531344.aspx
-        try ctx.args.append(c"legacy_stdio_definitions.lib");
+        try ctx.args.append("legacy_stdio_definitions.lib");
 
         // msvcrt depends on kernel32
-        try ctx.args.append(c"kernel32.lib");
+        try ctx.args.append("kernel32.lib");
     } else {
-        try ctx.args.append(c"-NODEFAULTLIB");
+        try ctx.args.append("-NODEFAULTLIB");
         if (!is_library) {
-            try ctx.args.append(c"-ENTRY:WinMainCRTStartup");
+            try ctx.args.append("-ENTRY:WinMainCRTStartup");
             // TODO
             //if (g->have_winmain) {
             //    lj->args.append("-ENTRY:WinMain");
@@ -385,7 +385,7 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
     }
 
     if (is_library and !ctx.comp.is_static) {
-        try ctx.args.append(c"-DLL");
+        try ctx.args.append("-DLL");
     }
 
     //for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
@@ -463,18 +463,18 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
 }
 
 fn constructLinkerArgsMachO(ctx: *Context) !void {
-    try ctx.args.append(c"-demangle");
+    try ctx.args.append("-demangle");
 
     if (ctx.comp.linker_rdynamic) {
-        try ctx.args.append(c"-export_dynamic");
+        try ctx.args.append("-export_dynamic");
     }
 
     const is_lib = ctx.comp.kind == Compilation.Kind.Lib;
     const shared = !ctx.comp.is_static and is_lib;
     if (ctx.comp.is_static) {
-        try ctx.args.append(c"-static");
+        try ctx.args.append("-static");
     } else {
-        try ctx.args.append(c"-dynamic");
+        try ctx.args.append("-dynamic");
     }
 
     //if (is_lib) {
@@ -503,7 +503,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
     //    }
     //}
 
-    try ctx.args.append(c"-arch");
+    try ctx.args.append("-arch");
     const darwin_arch_str = try std.cstr.addNullByte(
         &ctx.arena.allocator,
         ctx.comp.target.getDarwinArchString(),
@@ -512,22 +512,22 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
 
     const platform = try DarwinPlatform.get(ctx.comp);
     switch (platform.kind) {
-        DarwinPlatform.Kind.MacOS => try ctx.args.append(c"-macosx_version_min"),
-        DarwinPlatform.Kind.IPhoneOS => try ctx.args.append(c"-iphoneos_version_min"),
-        DarwinPlatform.Kind.IPhoneOSSimulator => try ctx.args.append(c"-ios_simulator_version_min"),
+        DarwinPlatform.Kind.MacOS => try ctx.args.append("-macosx_version_min"),
+        DarwinPlatform.Kind.IPhoneOS => try ctx.args.append("-iphoneos_version_min"),
+        DarwinPlatform.Kind.IPhoneOSSimulator => try ctx.args.append("-ios_simulator_version_min"),
     }
     const ver_str = try std.fmt.allocPrint(&ctx.arena.allocator, "{}.{}.{}\x00", platform.major, platform.minor, platform.micro);
     try ctx.args.append(ver_str.ptr);
 
     if (ctx.comp.kind == Compilation.Kind.Exe) {
         if (ctx.comp.is_static) {
-            try ctx.args.append(c"-no_pie");
+            try ctx.args.append("-no_pie");
         } else {
-            try ctx.args.append(c"-pie");
+            try ctx.args.append("-pie");
         }
     }
 
-    try ctx.args.append(c"-o");
+    try ctx.args.append("-o");
     try ctx.args.append(ctx.out_file_path.ptr());
 
     //for (size_t i = 0; i < g->rpath_list.length; i += 1) {
@@ -537,27 +537,27 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
     //add_rpath(lj, &lj->out_file);
 
     if (shared) {
-        try ctx.args.append(c"-headerpad_max_install_names");
+        try ctx.args.append("-headerpad_max_install_names");
     } else if (ctx.comp.is_static) {
-        try ctx.args.append(c"-lcrt0.o");
+        try ctx.args.append("-lcrt0.o");
     } else {
         switch (platform.kind) {
             DarwinPlatform.Kind.MacOS => {
                 if (platform.versionLessThan(10, 5)) {
-                    try ctx.args.append(c"-lcrt1.o");
+                    try ctx.args.append("-lcrt1.o");
                 } else if (platform.versionLessThan(10, 6)) {
-                    try ctx.args.append(c"-lcrt1.10.5.o");
+                    try ctx.args.append("-lcrt1.10.5.o");
                 } else if (platform.versionLessThan(10, 8)) {
-                    try ctx.args.append(c"-lcrt1.10.6.o");
+                    try ctx.args.append("-lcrt1.10.6.o");
                 }
             },
             DarwinPlatform.Kind.IPhoneOS => {
                 if (ctx.comp.target.getArch() == builtin.Arch.aarch64) {
                     // iOS does not need any crt1 files for arm64
                 } else if (platform.versionLessThan(3, 1)) {
-                    try ctx.args.append(c"-lcrt1.o");
+                    try ctx.args.append("-lcrt1.o");
                 } else if (platform.versionLessThan(6, 0)) {
-                    try ctx.args.append(c"-lcrt1.3.1.o");
+                    try ctx.args.append("-lcrt1.3.1.o");
                 }
             },
             DarwinPlatform.Kind.IPhoneOSSimulator => {}, // no crt1.o needed
@@ -589,7 +589,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
                 // to make syscalls because the syscall numbers are not documented
                 // and change between versions.
                 // so we always link against libSystem
-                try ctx.args.append(c"-lSystem");
+                try ctx.args.append("-lSystem");
             } else {
                 if (mem.indexOfScalar(u8, lib.name, '/') == null) {
                     const arg = try std.fmt.allocPrint(&ctx.arena.allocator, "-l{}\x00", lib.name);
@@ -601,15 +601,15 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
             }
         }
     } else {
-        try ctx.args.append(c"-undefined");
-        try ctx.args.append(c"dynamic_lookup");
+        try ctx.args.append("-undefined");
+        try ctx.args.append("dynamic_lookup");
     }
 
     if (platform.kind == DarwinPlatform.Kind.MacOS) {
         if (platform.versionLessThan(10, 5)) {
-            try ctx.args.append(c"-lgcc_s.10.4");
+            try ctx.args.append("-lgcc_s.10.4");
         } else if (platform.versionLessThan(10, 6)) {
-            try ctx.args.append(c"-lgcc_s.10.5");
+            try ctx.args.append("-lgcc_s.10.5");
         }
     } else {
         @panic("TODO");
src-self-hosted/stage1.zig
@@ -28,7 +28,7 @@ comptime {
 // ABI warning
 export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {
     const info_zen = @import("main.zig").info_zen;
-    ptr.* = &info_zen;
+    ptr.* = info_zen;
     len.* = info_zen.len;
 }
 
src-self-hosted/value.zig
@@ -474,7 +474,7 @@ pub const Value = struct {
                         dont_null_terminate,
                     ) orelse return error.OutOfMemory;
                     const str_init_type = llvm.TypeOf(llvm_str_init);
-                    const global = llvm.AddGlobal(ofile.module, str_init_type, c"") orelse return error.OutOfMemory;
+                    const global = llvm.AddGlobal(ofile.module, str_init_type, "") orelse return error.OutOfMemory;
                     llvm.SetInitializer(global, llvm_str_init);
                     llvm.SetLinkage(global, llvm.PrivateLinkage);
                     llvm.SetGlobalConstant(global, 1);
test/stage1/behavior/bugs/1076.zig
@@ -8,8 +8,16 @@ test "comptime code should not modify constant data" {
 }
 
 fn testCastPtrOfArrayToSliceAndPtr() void {
-    var array = "aoeu";
-    const x: [*]u8 = &array;
-    x[0] += 1;
-    expect(mem.eql(u8, array[0..], "boeu"));
+    {
+        var array = "aoeu".*;
+        const x: [*]u8 = &array;
+        x[0] += 1;
+        expect(mem.eql(u8, array[0..], "boeu"));
+    }
+    {
+        var array: [4]u8 = "aoeu".*;
+        const x: [*]u8 = &array;
+        x[0] += 1;
+        expect(mem.eql(u8, array[0..], "boeu"));
+    }
 }
test/stage1/behavior/array.zig
@@ -132,9 +132,16 @@ test "single-item pointer to array indexing and slicing" {
 }
 
 fn testSingleItemPtrArrayIndexSlice() void {
-    var array = "aaaa";
-    doSomeMangling(&array);
-    expect(mem.eql(u8, "azya", array));
+    {
+        var array: [4]u8 = "aaaa".*;
+        doSomeMangling(&array);
+        expect(mem.eql(u8, "azya", &array));
+    }
+    {
+        var array = "aaaa".*;
+        doSomeMangling(&array);
+        expect(mem.eql(u8, "azya", &array));
+    }
 }
 
 fn doSomeMangling(array: *[4]u8) void {
@@ -294,9 +301,16 @@ test "read/write through global variable array of struct fields initialized via
 }
 
 test "implicit cast zero sized array ptr to slice" {
-    var b = "";
-    const c: []const u8 = &b;
-    expect(c.len == 0);
+    {
+        var b = "".*;
+        const c: []const u8 = &b;
+        expect(c.len == 0);
+    }
+    {
+        var b: [0]u8 = "".*;
+        const c: []const u8 = &b;
+        expect(c.len == 0);
+    }
 }
 
 test "anonymous list literal syntax" {
@@ -333,3 +347,16 @@ test "anonymous literal in array" {
     S.doTheTest();
     comptime S.doTheTest();
 }
+
+test "access the null element of a null terminated array" {
+    const S = struct {
+        fn doTheTest() void {
+            var array: [4]null u8 = .{'a', 'o', 'e', 'u'};
+            comptime expect(array[4] == 0);
+            var len: usize = 4;
+            expect(array[len] == 0);
+        }
+    };
+    S.doTheTest();
+    comptime S.doTheTest();
+}
test/stage1/behavior/cast.zig
@@ -179,18 +179,24 @@ fn gimmeErrOrSlice() anyerror![]u8 {
 }
 
 test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" {
-    {
-        var data = "hi";
-        const slice = data[0..];
-        expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
-        expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
-    }
-    comptime {
-        var data = "hi";
-        const slice = data[0..];
-        expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
-        expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
-    }
+    const S = struct {
+        fn doTheTest() anyerror!void {
+            {
+                var data = "hi".*;
+                const slice = data[0..];
+                expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
+                expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
+            }
+            {
+                var data: [2]u8 = "hi".*;
+                const slice = data[0..];
+                expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
+                expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
+            }
+        }
+    };
+    try S.doTheTest();
+    try comptime S.doTheTest();
 }
 fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 {
     if (a) {
@@ -217,11 +223,20 @@ test "implicit cast from &const [N]T to []const T" {
 }
 
 fn testCastConstArrayRefToConstSlice() void {
-    const blah = "aoeu";
-    const const_array_ref = &blah;
-    expect(@typeOf(const_array_ref) == *const [4]u8);
-    const slice: []const u8 = const_array_ref;
-    expect(mem.eql(u8, slice, "aoeu"));
+    {
+        const blah = "aoeu".*;
+        const const_array_ref = &blah;
+        expect(@typeOf(const_array_ref) == *const [4]null u8);
+        const slice: []const u8 = const_array_ref;
+        expect(mem.eql(u8, slice, "aoeu"));
+    }
+    {
+        const blah: [4]u8 = "aoeu".*;
+        const const_array_ref = &blah;
+        expect(@typeOf(const_array_ref) == *const [4]u8);
+        const slice: []const u8 = const_array_ref;
+        expect(mem.eql(u8, slice, "aoeu"));
+    }
 }
 
 test "peer type resolution: error and [N]T" {
@@ -310,17 +325,28 @@ test "single-item pointer of array to slice and to unknown length pointer" {
 }
 
 fn testCastPtrOfArrayToSliceAndPtr() void {
-    var array = "aoeu";
-    const x: [*]u8 = &array;
-    x[0] += 1;
-    expect(mem.eql(u8, array[0..], "boeu"));
-    const y: []u8 = &array;
-    y[0] += 1;
-    expect(mem.eql(u8, array[0..], "coeu"));
+    {
+        var array = "aoeu".*;
+        const x: [*]u8 = &array;
+        x[0] += 1;
+        expect(mem.eql(u8, array[0..], "boeu"));
+        const y: []u8 = &array;
+        y[0] += 1;
+        expect(mem.eql(u8, array[0..], "coeu"));
+    }
+    {
+        var array: [4]u8 = "aoeu".*;
+        const x: [*]u8 = &array;
+        x[0] += 1;
+        expect(mem.eql(u8, array[0..], "boeu"));
+        const y: []u8 = &array;
+        y[0] += 1;
+        expect(mem.eql(u8, array[0..], "coeu"));
+    }
 }
 
 test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
-    const window_name = [1][*]const u8{c"window name"};
+    const window_name = [1][*]const u8{"window name"};
     const x: [*]const ?[*]const u8 = &window_name;
     expect(mem.eql(u8, std.mem.toSliceConst(u8, x[0].?), "window name"));
 }
@@ -545,7 +571,7 @@ test "implicit cast *[0]T to E![]const u8" {
 }
 
 test "peer cast *[0]T to E![]const T" {
-    var buffer: [5]u8 = "abcde";
+    var buffer: [5]u8 = "abcde".*;
     var buf: anyerror![]const u8 = buffer[0..];
     var b = false;
     var y = if (b) &[0]u8{} else buf;
@@ -553,7 +579,7 @@ test "peer cast *[0]T to E![]const T" {
 }
 
 test "peer cast *[0]T to []const T" {
-    var buffer: [5]u8 = "abcde";
+    var buffer: [5]u8 = "abcde".*;
     var buf: []const u8 = buffer[0..];
     var b = false;
     var y = if (b) &[0]u8{} else buf;
@@ -565,3 +591,33 @@ test "cast from array reference to fn" {
     const f = @ptrCast(extern fn () void, &global_array);
     expect(@ptrToInt(f) == @ptrToInt(&global_array));
 }
+
+test "*const [N]null u8 to ?[]const u8" {
+    const S = struct {
+        fn doTheTest() void {
+            var a = "Hello";
+            var b: ?[]const u8 = a;
+            expect(mem.eql(u8, b.?, "Hello"));
+        }
+    };
+    S.doTheTest();
+    comptime S.doTheTest();
+}
+
+test "peer resolution of string literals" {
+    const S = struct {
+        const E = extern enum { a, b, c, d};
+
+        fn doTheTest(e: E) void {
+            const cmd = switch (e) {
+                .a => "one",
+                .b => "two",
+                .c => "three",
+                .d => "four",
+            };
+            expect(mem.eql(u8, cmd, "two"));
+        }
+    };
+    S.doTheTest(.b);
+    comptime S.doTheTest(.b);
+}
test/stage1/behavior/const_slice_child.zig
@@ -6,12 +6,11 @@ var argv: [*]const [*]const u8 = undefined;
 
 test "const slice child" {
     const strs = [_][*]const u8{
-        c"one",
-        c"two",
-        c"three",
+        "one",
+        "two",
+        "three",
     };
-    // TODO this should implicitly cast
-    argv = @ptrCast([*]const [*]const u8, &strs);
+    argv = &strs;
     bar(strs.len);
 }
 
test/stage1/behavior/eval.zig
@@ -736,7 +736,7 @@ test "comptime pointer cast array and then slice" {
 
 test "slice bounds in comptime concatenation" {
     const bs = comptime blk: {
-        const b = c"........1........";
+        const b = "........1........";
         break :blk b[8..9];
     };
     const str = "" ++ bs;
test/stage1/behavior/misc.zig
@@ -204,11 +204,11 @@ test "multiline string" {
 
 test "multiline C string" {
     const s1 =
-        c\\one
-        c\\two)
-        c\\three
+        \\one
+        \\two)
+        \\three
     ;
-    const s2 = c"one\ntwo)\nthree";
+    const s2 = "one\ntwo)\nthree";
     expect(std.cstr.cmp(s1, s2) == 0);
 }
 
@@ -358,9 +358,12 @@ fn ptrEql(a: *const []const u8, b: *const []const u8) bool {
     return a == b;
 }
 
-test "C string concatenation" {
-    const a = c"OK" ++ c" IT " ++ c"WORKED";
-    const b = c"OK IT WORKED";
+test "string concatenation" {
+    const a = "OK" ++ " IT " ++ "WORKED";
+    const b = "OK IT WORKED";
+
+    comptime expect(@typeOf(a) == *const [12]null u8);
+    comptime expect(@typeOf(b) == *const [12]null u8);
 
     const len = mem.len(u8, b);
     const len_with_null = len + 1;
test/stage1/behavior/pointers.zig
@@ -15,7 +15,7 @@ fn testDerefPtr() void {
 }
 
 test "pointer arithmetic" {
-    var ptr = c"abcd";
+    var ptr: [*]const u8 = "abcd";
 
     expect(ptr[0] == 'a');
     ptr += 1;
test/stage1/behavior/ptrcast.zig
@@ -60,7 +60,7 @@ test "comptime ptrcast keeps larger alignment" {
 }
 
 test "implicit optional pointer to optional c_void pointer" {
-    var buf: [4]u8 = "aoeu";
+    var buf: [4]u8 = "aoeu".*;
     var x: ?[*]u8 = &buf;
     var y: ?*c_void = x;
     var z = @ptrCast(*[4]u8, y);
test/stage1/behavior/slice.zig
@@ -36,7 +36,7 @@ fn assertLenIsZero(msg: []const u8) void {
 }
 
 test "C pointer" {
-    var buf: [*c]const u8 = c"kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";
+    var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";
     var len: u32 = 10;
     var slice = buf[0..len];
     expectEqualSlices(u8, "kjdhfkjdhf", slice);
test/stage1/behavior/struct.zig
@@ -493,7 +493,7 @@ test "non-byte-aligned array inside packed struct" {
         fn doTheTest() void {
             var foo = Foo{
                 .a = true,
-                .b = "abcdefghijklmnopqurstu",
+                .b = "abcdefghijklmnopqurstu".*,
             };
             bar(foo.b);
         }
test/stage2/compare_output.zig
@@ -6,7 +6,7 @@ pub fn addCases(ctx: *TestContext) !void {
     try ctx.testCompareOutputLibC(
         \\extern fn puts([*]const u8) void;
         \\export fn main() c_int {
-        \\    puts(c"Hello, world!");
+        \\    puts("Hello, world!");
         \\    return 0;
         \\}
     , "Hello, world!" ++ std.cstr.line_sep);
@@ -15,7 +15,7 @@ pub fn addCases(ctx: *TestContext) !void {
     try ctx.testCompareOutputLibC(
         \\extern fn puts(s: [*]const u8) void;
         \\export fn main() c_int {
-        \\    return foo(c"OK");
+        \\    return foo("OK");
         \\}
         \\fn foo(s: [*]const u8) c_int {
         \\    puts(s);
test/standalone/hello_world/hello_libc.zig
@@ -5,7 +5,7 @@ const c = @cImport({
     @cInclude("string.h");
 });
 
-const msg = c"Hello, world!\n";
+const msg = "Hello, world!\n";
 
 export fn main(argc: c_int, argv: **u8) c_int {
     if (c.printf(msg) != @intCast(c_int, c.strlen(msg))) return -1;
test/compare_output.zig
@@ -7,7 +7,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
     cases.addC("hello world with libc",
         \\const c = @cImport(@cInclude("stdio.h"));
         \\export fn main(argc: c_int, argv: [*][*]u8) c_int {
-        \\    _ = c.puts(c"Hello, world!");
+        \\    _ = c.puts("Hello, world!");
         \\    return 0;
         \\}
     , "Hello, world!" ++ std.cstr.line_sep);
@@ -144,75 +144,75 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
         \\        // we want actual \n, not \r\n
         \\        _ = c._setmode(1, c._O_BINARY);
         \\    }
-        \\    _ = c.printf(c"0: %llu\n",
+        \\    _ = c.printf("0: %llu\n",
         \\             @as(u64, 0));
-        \\    _ = c.printf(c"320402575052271: %llu\n",
+        \\    _ = c.printf("320402575052271: %llu\n",
         \\         @as(u64, 320402575052271));
-        \\    _ = c.printf(c"0x01236789abcdef: %llu\n",
+        \\    _ = c.printf("0x01236789abcdef: %llu\n",
         \\         @as(u64, 0x01236789abcdef));
-        \\    _ = c.printf(c"0xffffffffffffffff: %llu\n",
+        \\    _ = c.printf("0xffffffffffffffff: %llu\n",
         \\         @as(u64, 0xffffffffffffffff));
-        \\    _ = c.printf(c"0x000000ffffffffffffffff: %llu\n",
+        \\    _ = c.printf("0x000000ffffffffffffffff: %llu\n",
         \\         @as(u64, 0x000000ffffffffffffffff));
-        \\    _ = c.printf(c"0o1777777777777777777777: %llu\n",
+        \\    _ = c.printf("0o1777777777777777777777: %llu\n",
         \\         @as(u64, 0o1777777777777777777777));
-        \\    _ = c.printf(c"0o0000001777777777777777777777: %llu\n",
+        \\    _ = c.printf("0o0000001777777777777777777777: %llu\n",
         \\         @as(u64, 0o0000001777777777777777777777));
-        \\    _ = c.printf(c"0b1111111111111111111111111111111111111111111111111111111111111111: %llu\n",
+        \\    _ = c.printf("0b1111111111111111111111111111111111111111111111111111111111111111: %llu\n",
         \\         @as(u64, 0b1111111111111111111111111111111111111111111111111111111111111111));
-        \\    _ = c.printf(c"0b0000001111111111111111111111111111111111111111111111111111111111111111: %llu\n",
+        \\    _ = c.printf("0b0000001111111111111111111111111111111111111111111111111111111111111111: %llu\n",
         \\         @as(u64, 0b0000001111111111111111111111111111111111111111111111111111111111111111));
         \\
-        \\    _ = c.printf(c"\n");
+        \\    _ = c.printf("\n");
         \\
-        \\    _ = c.printf(c"0.0: %.013a\n",
+        \\    _ = c.printf("0.0: %.013a\n",
         \\         @as(f64, 0.0));
-        \\    _ = c.printf(c"0e0: %.013a\n",
+        \\    _ = c.printf("0e0: %.013a\n",
         \\         @as(f64, 0e0));
-        \\    _ = c.printf(c"0.0e0: %.013a\n",
+        \\    _ = c.printf("0.0e0: %.013a\n",
         \\         @as(f64, 0.0e0));
-        \\    _ = c.printf(c"000000000000000000000000000000000000000000000000000000000.0e0: %.013a\n",
+        \\    _ = c.printf("000000000000000000000000000000000000000000000000000000000.0e0: %.013a\n",
         \\         @as(f64, 000000000000000000000000000000000000000000000000000000000.0e0));
-        \\    _ = c.printf(c"0.000000000000000000000000000000000000000000000000000000000e0: %.013a\n",
+        \\    _ = c.printf("0.000000000000000000000000000000000000000000000000000000000e0: %.013a\n",
         \\         @as(f64, 0.000000000000000000000000000000000000000000000000000000000e0));
-        \\    _ = c.printf(c"0.0e000000000000000000000000000000000000000000000000000000000: %.013a\n",
+        \\    _ = c.printf("0.0e000000000000000000000000000000000000000000000000000000000: %.013a\n",
         \\         @as(f64, 0.0e000000000000000000000000000000000000000000000000000000000));
-        \\    _ = c.printf(c"1.0: %.013a\n",
+        \\    _ = c.printf("1.0: %.013a\n",
         \\         @as(f64, 1.0));
-        \\    _ = c.printf(c"10.0: %.013a\n",
+        \\    _ = c.printf("10.0: %.013a\n",
         \\         @as(f64, 10.0));
-        \\    _ = c.printf(c"10.5: %.013a\n",
+        \\    _ = c.printf("10.5: %.013a\n",
         \\         @as(f64, 10.5));
-        \\    _ = c.printf(c"10.5e5: %.013a\n",
+        \\    _ = c.printf("10.5e5: %.013a\n",
         \\         @as(f64, 10.5e5));
-        \\    _ = c.printf(c"10.5e+5: %.013a\n",
+        \\    _ = c.printf("10.5e+5: %.013a\n",
         \\         @as(f64, 10.5e+5));
-        \\    _ = c.printf(c"50.0e-2: %.013a\n",
+        \\    _ = c.printf("50.0e-2: %.013a\n",
         \\         @as(f64, 50.0e-2));
-        \\    _ = c.printf(c"50e-2: %.013a\n",
+        \\    _ = c.printf("50e-2: %.013a\n",
         \\         @as(f64, 50e-2));
         \\
-        \\    _ = c.printf(c"\n");
+        \\    _ = c.printf("\n");
         \\
-        \\    _ = c.printf(c"0x1.0: %.013a\n",
+        \\    _ = c.printf("0x1.0: %.013a\n",
         \\         @as(f64, 0x1.0));
-        \\    _ = c.printf(c"0x10.0: %.013a\n",
+        \\    _ = c.printf("0x10.0: %.013a\n",
         \\         @as(f64, 0x10.0));
-        \\    _ = c.printf(c"0x100.0: %.013a\n",
+        \\    _ = c.printf("0x100.0: %.013a\n",
         \\         @as(f64, 0x100.0));
-        \\    _ = c.printf(c"0x103.0: %.013a\n",
+        \\    _ = c.printf("0x103.0: %.013a\n",
         \\         @as(f64, 0x103.0));
-        \\    _ = c.printf(c"0x103.7: %.013a\n",
+        \\    _ = c.printf("0x103.7: %.013a\n",
         \\         @as(f64, 0x103.7));
-        \\    _ = c.printf(c"0x103.70: %.013a\n",
+        \\    _ = c.printf("0x103.70: %.013a\n",
         \\         @as(f64, 0x103.70));
-        \\    _ = c.printf(c"0x103.70p4: %.013a\n",
+        \\    _ = c.printf("0x103.70p4: %.013a\n",
         \\         @as(f64, 0x103.70p4));
-        \\    _ = c.printf(c"0x103.70p5: %.013a\n",
+        \\    _ = c.printf("0x103.70p5: %.013a\n",
         \\         @as(f64, 0x103.70p5));
-        \\    _ = c.printf(c"0x103.70p+5: %.013a\n",
+        \\    _ = c.printf("0x103.70p+5: %.013a\n",
         \\         @as(f64, 0x103.70p+5));
-        \\    _ = c.printf(c"0x103.70p-5: %.013a\n",
+        \\    _ = c.printf("0x103.70p-5: %.013a\n",
         \\         @as(f64, 0x103.70p-5));
         \\
         \\    return 0;
@@ -323,7 +323,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
         \\    const x: f64 = small;
         \\    const y = @floatToInt(i32, x);
         \\    const z = @intToFloat(f64, y);
-        \\    _ = c.printf(c"%.2f\n%d\n%.2f\n%.2f\n", x, y, z, @as(f64, -0.4));
+        \\    _ = c.printf("%.2f\n%d\n%.2f\n%.2f\n", x, y, z, @as(f64, -0.4));
         \\    return 0;
         \\}
     , "3.25\n3\n3.00\n-0.40\n");
test/compile_errors.zig
@@ -164,7 +164,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
     cases.add(
         "using an unknown len ptr type instead of array",
         \\const resolutions = [*][*]const u8{
-        \\    c"[320 240  ]",
+        \\    "[320 240  ]",
         \\    null,
         \\};
         \\comptime {
@@ -781,7 +781,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         "peer cast then implicit cast const pointer to mutable C pointer",
         \\export fn func() void {
         \\    var strValue: [*c]u8 = undefined;
-        \\    strValue = strValue orelse c"";
+        \\    strValue = strValue orelse "";
         \\}
     ,
         "tmp.zig:3:32: error: cast discards const qualifier",
@@ -1115,7 +1115,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
             "libc headers note",
             \\const c = @cImport(@cInclude("stdio.h"));
             \\export fn entry() void {
-            \\    _ = c.printf(c"hello, world!\n");
+            \\    _ = c.printf("hello, world!\n");
             \\}
         ,
             "tmp.zig:1:11: error: C import failed",
@@ -3352,7 +3352,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
     cases.add(
         "variable has wrong type",
         \\export fn f() i32 {
-        \\    const a = c"a";
+        \\    const a = "a";
         \\    return a;
         \\}
     ,
@@ -4786,7 +4786,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
     cases.add(
         "assign through constant pointer",
         \\export fn f() void {
-        \\  var cstr = c"Hat";
+        \\  var cstr = "Hat";
         \\  cstr[0] = 'W';
         \\}
     ,
test/translate_c.zig
@@ -47,7 +47,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\pub fn foo() void {
         \\    var a: c_int = undefined;
         \\    _ = 1;
-        \\    _ = c"hey";
+        \\    _ = "hey";
         \\    _ = (1 + 1);
         \\    _ = (1 - 1);
         \\    a = 1;
@@ -213,9 +213,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
     ,
         \\pub fn foo() void {
-        \\    _ = c"foo";
-        \\    _ = c"foo";
-        \\    _ = c"void foo(void)";
+        \\    _ = "foo";
+        \\    _ = "foo";
+        \\    _ = "void foo(void)";
         \\}
     );
 
@@ -232,7 +232,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\pub fn foo() void {
         \\    var a: c_int = undefined;
         \\    _ = 1;
-        \\    _ = c"hey";
+        \\    _ = "hey";
         \\    _ = (1 + 1);
         \\    _ = (1 - 1);
         \\    a = 1;
@@ -543,7 +543,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
     cases.add("#define string",
         \\#define  foo  "a string"
     ,
-        \\pub const foo = c"a string";
+        \\pub const foo = "a string";
     );
 
     cases.add("__cdecl doesn't mess up function pointers",
@@ -617,9 +617,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\#define FOO2 "aoeu\x0007a derp"
         \\#define FOO_CHAR '\xfF'
     ,
-        \\pub const FOO = c"aoeu\xab derp";
+        \\pub const FOO = "aoeu\xab derp";
     ,
-        \\pub const FOO2 = c"aoeuz derp";
+        \\pub const FOO2 = "aoeuz derp";
     ,
         \\pub const FOO_CHAR = 255;
     );
@@ -629,9 +629,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\#define FOO2 "aoeu\0234 derp"
         \\#define FOO_CHAR '\077'
     ,
-        \\pub const FOO = c"aoeu\x13 derp";
+        \\pub const FOO = "aoeu\x13 derp";
     ,
-        \\pub const FOO2 = c"aoeu\x134 derp";
+        \\pub const FOO2 = "aoeu\x134 derp";
     ,
         \\pub const FOO_CHAR = 63;
     );
@@ -1351,7 +1351,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
     ,
         \\pub fn foo() [*c]const u8 {
-        \\    return c"bar";
+        \\    return "bar";
         \\}
     );
 
@@ -1523,7 +1523,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
     cases.add("const ptr initializer",
         \\static const char *v0 = "0.0.0";
     ,
-        \\pub var v0: [*c]const u8 = c"0.0.0";
+        \\pub var v0: [*c]const u8 = "0.0.0";
     );
 
     cases.add("static incomplete array inside function",
@@ -1532,7 +1532,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
     ,
         \\pub fn foo() void {
-        \\    const v2: [*c]const u8 = c"2.2.2";
+        \\    const v2: [*c]const u8 = "2.2.2";
         \\}
     );
 
@@ -1809,7 +1809,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\    var i: u8 = @as(u8, '\x0b');
         \\    var j: u8 = @as(u8, '\x00');
         \\    var k: u8 = @as(u8, '\"');
-        \\    return c"\'\\\x07\x08\x0c\n\r\t\x0b\x00\"";
+        \\    return "\'\\\x07\x08\x0c\n\r\t\x0b\x00\"";
         \\}
         \\
     );