Commit e9a03cccf3

Andrew Kelley <superjoe30@gmail.com>
2018-07-16 16:53:15
all integer sizes are available as primitives
* fix wrong implicit cast for `@IntType` bit_count parameter. * fix incorrect docs for `@IntType` bit_count parameter. closes #1242 closes #745 closes #1240
1 parent 363f4fa
doc/langref.html.in
@@ -2310,11 +2310,11 @@ test "while loop continue expression" {
 }
 
 test "while loop continue expression, more complicated" {
-    var i1: usize = 1;
-    var j1: usize = 1;
-    while (i1 * j1 < 2000) : ({ i1 *= 2; j1 *= 3; }) {
-        const my_ij1 = i1 * j1;
-        assert(my_ij1 < 2000);
+    var i: usize = 1;
+    var j: usize = 1;
+    while (i * j < 2000) : ({ i *= 2; j *= 3; }) {
+        const my_ij = i * j;
+        assert(my_ij < 2000);
     }
 }
       {#code_end#}
@@ -5424,7 +5424,7 @@ fn add(a: i32, b: i32) i32 { return a + b; }
       {#header_close#}
 
       {#header_open|@IntType#}
-      <pre><code class="zig">@IntType(comptime is_signed: bool, comptime bit_count: u8) type</code></pre>
+      <pre><code class="zig">@IntType(comptime is_signed: bool, comptime bit_count: u32) type</code></pre>
       <p>
       This function returns an integer type with the given signness and bit count.
       </p>
src/all_types.hpp
@@ -1587,7 +1587,6 @@ struct CodeGen {
 
     struct {
         TypeTableEntry *entry_bool;
-        TypeTableEntry *entry_int[2][12]; // [signed,unsigned][2,3,4,5,6,7,8,16,29,32,64,128]
         TypeTableEntry *entry_c_int[CIntTypeCount];
         TypeTableEntry *entry_c_longdouble;
         TypeTableEntry *entry_c_void;
@@ -1596,12 +1595,9 @@ struct CodeGen {
         TypeTableEntry *entry_u32;
         TypeTableEntry *entry_u29;
         TypeTableEntry *entry_u64;
-        TypeTableEntry *entry_u128;
         TypeTableEntry *entry_i8;
-        TypeTableEntry *entry_i16;
         TypeTableEntry *entry_i32;
         TypeTableEntry *entry_i64;
-        TypeTableEntry *entry_i128;
         TypeTableEntry *entry_isize;
         TypeTableEntry *entry_usize;
         TypeTableEntry *entry_f16;
src/analyze.cpp
@@ -3227,9 +3227,8 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
     }
 
     {
-        auto entry = g->primitive_type_table.maybe_get(tld->name);
-        if (entry) {
-            TypeTableEntry *type = entry->value;
+        TypeTableEntry *type = get_primitive_type(g, tld->name);
+        if (type != nullptr) {
             add_node_error(g, tld->source_node,
                     buf_sprintf("declaration shadows type '%s'", buf_ptr(&type->name)));
         }
@@ -3474,9 +3473,8 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
             add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
             variable_entry->value->type = g->builtin_types.entry_invalid;
         } else {
-            auto primitive_table_entry = g->primitive_type_table.maybe_get(name);
-            if (primitive_table_entry) {
-                TypeTableEntry *type = primitive_table_entry->value;
+            TypeTableEntry *type = get_primitive_type(g, name);
+            if (type != nullptr) {
                 add_node_error(g, source_node,
                         buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));
                 variable_entry->value->type = g->builtin_types.entry_invalid;
@@ -4307,43 +4305,7 @@ void semantic_analyze(CodeGen *g) {
     }
 }
 
-TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
-    size_t index;
-    if (size_in_bits == 2) {
-        index = 0;
-    } else if (size_in_bits == 3) {
-        index = 1;
-    } else if (size_in_bits == 4) {
-        index = 2;
-    } else if (size_in_bits == 5) {
-        index = 3;
-    } else if (size_in_bits == 6) {
-        index = 4;
-    } else if (size_in_bits == 7) {
-        index = 5;
-    } else if (size_in_bits == 8) {
-        index = 6;
-    } else if (size_in_bits == 16) {
-        index = 7;
-    } else if (size_in_bits == 29) {
-        index = 8;
-    } else if (size_in_bits == 32) {
-        index = 9;
-    } else if (size_in_bits == 64) {
-        index = 10;
-    } else if (size_in_bits == 128) {
-        index = 11;
-    } else {
-        return nullptr;
-    }
-    return &g->builtin_types.entry_int[is_signed ? 0 : 1][index];
-}
-
 TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
-    TypeTableEntry **common_entry = get_int_type_ptr(g, is_signed, size_in_bits);
-    if (common_entry)
-        return *common_entry;
-
     TypeId type_id = {};
     type_id.id = TypeTableEntryIdInt;
     type_id.data.integer.is_signed = is_signed;
@@ -4953,6 +4915,8 @@ bool fn_eval_cacheable(Scope *scope, TypeTableEntry *return_type) {
     while (scope) {
         if (scope->id == ScopeIdVarDecl) {
             ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
+            if (type_is_invalid(var_scope->var->value->type))
+                return false;
             if (can_mutate_comptime_var_state(var_scope->var->value))
                 return false;
         } else if (scope->id == ScopeIdFnDef) {
@@ -6310,3 +6274,28 @@ bool type_can_fail(TypeTableEntry *type_entry) {
 bool fn_type_can_fail(FnTypeId *fn_type_id) {
     return type_can_fail(fn_type_id->return_type) || fn_type_id->cc == CallingConventionAsync;
 }
+
+TypeTableEntry *get_primitive_type(CodeGen *g, Buf *name) {
+    if (buf_len(name) >= 2) {
+        uint8_t first_c = buf_ptr(name)[0];
+        if (first_c == 'i' || first_c == 'u') {
+            for (size_t i = 1; i < buf_len(name); i += 1) {
+                uint8_t c = buf_ptr(name)[i];
+                if (c < '0' || c > '9') {
+                    goto not_integer;
+                }
+            }
+            bool is_signed = (first_c == 'i');
+            uint32_t bit_count = atoi(buf_ptr(name) + 1);
+            return get_int_type(g, is_signed, bit_count);
+        }
+    }
+
+not_integer:
+
+    auto primitive_table_entry = g->primitive_type_table.maybe_get(name);
+    if (primitive_table_entry != nullptr) {
+        return primitive_table_entry->value;
+    }
+    return nullptr;
+}
src/analyze.hpp
@@ -19,7 +19,6 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
         bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count);
 uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);
 uint64_t type_size_bits(CodeGen *g, TypeTableEntry *type_entry);
-TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_bits);
 TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
 TypeTableEntry **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type);
 TypeTableEntry *get_c_int_type(CodeGen *g, CIntType c_int_type);
@@ -204,4 +203,6 @@ bool type_can_fail(TypeTableEntry *type_entry);
 bool fn_eval_cacheable(Scope *scope, TypeTableEntry *return_type);
 AstNode *type_decl_node(TypeTableEntry *type_entry);
 
+TypeTableEntry *get_primitive_type(CodeGen *g, Buf *name);
+
 #endif
src/codegen.cpp
@@ -6161,16 +6161,6 @@ static void define_builtin_types(CodeGen *g) {
         g->builtin_types.entry_arg_tuple = entry;
     }
 
-    for (size_t int_size_i = 0; int_size_i < array_length(int_sizes_in_bits); int_size_i += 1) {
-        uint8_t size_in_bits = int_sizes_in_bits[int_size_i];
-        for (size_t is_sign_i = 0; is_sign_i < array_length(is_signed_list); is_sign_i += 1) {
-            bool is_signed = is_signed_list[is_sign_i];
-            TypeTableEntry *entry = make_int_type(g, is_signed, size_in_bits);
-            g->primitive_type_table.put(&entry->name, entry);
-            get_int_type_ptr(g, is_signed, size_in_bits)[0] = entry;
-        }
-    }
-
     for (size_t i = 0; i < array_length(c_int_type_infos); i += 1) {
         const CIntTypeInfo *info = &c_int_type_infos[i];
         uint32_t size_in_bits = target_c_type_size_in_bits(&g->zig_target, info->id);
@@ -6286,12 +6276,9 @@ static void define_builtin_types(CodeGen *g) {
     g->builtin_types.entry_u29 = get_int_type(g, false, 29);
     g->builtin_types.entry_u32 = get_int_type(g, false, 32);
     g->builtin_types.entry_u64 = get_int_type(g, false, 64);
-    g->builtin_types.entry_u128 = get_int_type(g, false, 128);
     g->builtin_types.entry_i8 = get_int_type(g, true, 8);
-    g->builtin_types.entry_i16 = get_int_type(g, true, 16);
     g->builtin_types.entry_i32 = get_int_type(g, true, 32);
     g->builtin_types.entry_i64 = get_int_type(g, true, 64);
-    g->builtin_types.entry_i128 = get_int_type(g, true, 128);
 
     {
         g->builtin_types.entry_c_void = get_opaque_type(g, nullptr, nullptr, "c_void");
src/ir.cpp
@@ -3217,9 +3217,8 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco
             add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
             variable_entry->value->type = codegen->builtin_types.entry_invalid;
         } else {
-            auto primitive_table_entry = codegen->primitive_type_table.maybe_get(name);
-            if (primitive_table_entry) {
-                TypeTableEntry *type = primitive_table_entry->value;
+            TypeTableEntry *type = get_primitive_type(codegen, name);
+            if (type != nullptr) {
                 add_node_error(codegen, node,
                         buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));
                 variable_entry->value->type = codegen->builtin_types.entry_invalid;
@@ -3661,9 +3660,9 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
         return &const_instruction->base;
     }
 
-    auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);
-    if (primitive_table_entry) {
-        IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value);
+    TypeTableEntry *primitive_type = get_primitive_type(irb->codegen, variable_name);
+    if (primitive_type != nullptr) {
+        IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_type);
         if (lval == LValPtr) {
             return ir_build_ref(irb, scope, node, value, false, false);
         } else {
@@ -10691,11 +10690,11 @@ static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out
     return true;
 }
 
-static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) {
+static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *int_type, uint64_t *out) {
     if (type_is_invalid(value->value.type))
         return false;
 
-    IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_usize);
+    IrInstruction *casted_value = ir_implicit_cast(ira, value, int_type);
     if (type_is_invalid(casted_value->value.type))
         return false;
 
@@ -10707,6 +10706,10 @@ static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out
     return true;
 }
 
+static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) {
+    return ir_resolve_unsigned(ira, value, ira->codegen->builtin_types.entry_usize, out);
+}
+
 static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *value, bool *out) {
     if (type_is_invalid(value->value.type))
         return false;
@@ -18025,7 +18028,7 @@ static TypeTableEntry *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstruc
 
     IrInstruction *bit_count_value = instruction->bit_count->other;
     uint64_t bit_count;
-    if (!ir_resolve_usize(ira, bit_count_value, &bit_count))
+    if (!ir_resolve_unsigned(ira, bit_count_value, ira->codegen->builtin_types.entry_u32, &bit_count))
         return ira->codegen->builtin_types.entry_invalid;
 
     ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
src/translate_c.cpp
@@ -427,7 +427,7 @@ static AstNode *get_global(Context *c, Buf *name) {
         if (entry)
             return entry->value;
     }
-    if (c->codegen->primitive_type_table.maybe_get(name) != nullptr) {
+    if (get_primitive_type(c->codegen, name) != nullptr) {
         return trans_create_node_symbol(c, name);
     }
     return nullptr;
std/crypto/sha1.zig
@@ -4,8 +4,6 @@ const endian = @import("../endian.zig");
 const debug = @import("../debug/index.zig");
 const builtin = @import("builtin");
 
-pub const u160 = @IntType(false, 160);
-
 const RoundParam = struct {
     a: usize,
     b: usize,
std/math/big/int.zig
@@ -996,7 +996,6 @@ pub const Int = struct {
 // They will still run on larger than this and should pass, but the multi-limb code-paths
 // may be untested in some cases.
 
-const u256 = @IntType(false, 256);
 const al = debug.global_allocator;
 
 test "big.int comptime_int set" {
std/math/exp2.zig
@@ -75,18 +75,18 @@ fn exp2_32(x: f32) f32 {
     }
 
     var uf = x + redux;
-    var i0 = @bitCast(u32, uf);
-    i0 += tblsiz / 2;
+    var i_0 = @bitCast(u32, uf);
+    i_0 += tblsiz / 2;
 
-    const k = i0 / tblsiz;
+    const k = i_0 / tblsiz;
     // NOTE: musl relies on undefined overflow shift behaviour. Appears that this produces the
     // intended result but should confirm how GCC/Clang handle this to ensure.
     const uk = @bitCast(f64, u64(0x3FF + k) << 52);
-    i0 &= tblsiz - 1;
+    i_0 &= tblsiz - 1;
     uf -= redux;
 
     const z: f64 = x - uf;
-    var r: f64 = exp2ft[i0];
+    var r: f64 = exp2ft[i_0];
     const t: f64 = r * z;
     r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);
     return @floatCast(f32, r * uk);
@@ -401,18 +401,18 @@ fn exp2_64(x: f64) f64 {
     // reduce x
     var uf = x + redux;
     // NOTE: musl performs an implicit 64-bit to 32-bit u32 truncation here
-    var i0 = @truncate(u32, @bitCast(u64, uf));
-    i0 += tblsiz / 2;
+    var i_0 = @truncate(u32, @bitCast(u64, uf));
+    i_0 += tblsiz / 2;
 
-    const k: u32 = i0 / tblsiz * tblsiz;
+    const k: u32 = i_0 / tblsiz * tblsiz;
     const ik = @bitCast(i32, k / tblsiz);
-    i0 %= tblsiz;
+    i_0 %= tblsiz;
     uf -= redux;
 
-    // r = exp2(y) = exp2t[i0] * p(z - eps[i])
+    // r = exp2(y) = exp2t[i_0] * p(z - eps[i])
     var z = x - uf;
-    const t = exp2dt[2 * i0];
-    z -= exp2dt[2 * i0 + 1];
+    const t = exp2dt[2 * i_0];
+    z -= exp2dt[2 * i_0 + 1];
     const r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
 
     return math.scalbn(r, ik);
std/math/index.zig
@@ -354,7 +354,7 @@ test "math.rotl" {
 
 pub fn Log2Int(comptime T: type) type {
     // comptime ceil log2
-    comptime var count: usize = 0;
+    comptime var count = 0;
     comptime var s = T.bit_count - 1;
     inline while (s != 0) : (s >>= 1) {
         count += 1;
std/os/time.zig
@@ -25,7 +25,6 @@ pub fn sleep(seconds: usize, nanoseconds: usize) void {
     }
 }
 
-const u63 = @IntType(false, 63);
 pub fn posixSleep(seconds: u63, nanoseconds: u63) void {
     var req = posix.timespec{
         .tv_sec = seconds,
std/buffer.zig
@@ -5,8 +5,6 @@ const Allocator = mem.Allocator;
 const assert = debug.assert;
 const ArrayList = std.ArrayList;
 
-const fmt = std.fmt;
-
 /// A buffer that allocates memory and maintains a null byte at the end.
 pub const Buffer = struct {
     list: ArrayList(u8),
std/json.zig
@@ -6,9 +6,6 @@ const std = @import("index.zig");
 const debug = std.debug;
 const mem = std.mem;
 
-const u1 = @IntType(false, 1);
-const u256 = @IntType(false, 256);
-
 // A single token slice into the parent string.
 //
 // Use `token.slice()` on the input at the current position to get the current slice.
test/cases/misc.zig
@@ -58,11 +58,6 @@ test "floating point primitive bit counts" {
     assert(f64.bit_count == 64);
 }
 
-const u1 = @IntType(false, 1);
-const u63 = @IntType(false, 63);
-const i1 = @IntType(true, 1);
-const i63 = @IntType(true, 63);
-
 test "@minValue and @maxValue" {
     assert(@maxValue(u1) == 1);
     assert(@maxValue(u8) == 255);
test/cases/struct.zig
@@ -240,7 +240,6 @@ fn getC(data: *const BitField1) u2 {
     return data.c;
 }
 
-const u24 = @IntType(false, 24);
 const Foo24Bits = packed struct {
     field: u24,
 };
test/compile_errors.zig
@@ -1,6 +1,15 @@
 const tests = @import("tests.zig");
 
 pub fn addCases(cases: *tests.CompileErrorContext) void {
+    cases.add(
+        "optional pointer to void in extern struct",
+        \\comptime {
+        \\    _ = @IntType(false, @maxValue(u32) + 1);
+        \\}
+    ,
+        ".tmp_source.zig:2:40: error: integer value 4294967296 cannot be implicitly casted to type 'u32'",
+    );
+
     cases.add(
         "optional pointer to void in extern struct",
         \\const Foo = extern struct {